Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

Documentation

analysis -- condition qualifier for conditions used by static analysis tools

analysis is a condition qualifier that is used for conditions that are
not intended to be checked at run time but only by static analysis tools.

array -- create initialized one-dimensional immutable array

array -- one-dimensional immutable array

This is the result type of array<T>(i32, i32 -> T) which creates an
initalized immutable array

array(length0, length1)

array provides two-dimensional immutable arrays. These are actually
one-dimensional immutable arrays with an additional access function with
two index parameters.

§array3<T>(length0 i32, length1 i32, length2 i32, init3 Function<array3.T, i32, i32, i32>)
 => 
array3<array3.T>
:
array<T>

array(length0, length1, length2)

array provides three-dimensional immutable arrays. These are actually
one-dimensional immutable arrays with an additional access function with
three index parameters.

bitset -- persistent set of unsigned integers

bitsets -- unit type defining features related to bitest but not
requiring an instance

bool -- Standard Fuzion type 'bool'

We need to apologize to George Boole for crippling his name a bit,
just to safe us from typing one more letter. But at least we stop
here and do not use boo, bo or similar.

bool is a choice type that can either be TRUE of FALSE.

Note that 'TRUE' and 'FALSE' themselves are not of type 'bool'.
Routines 'true' and 'false' are the preferred way to get a constant
value of type 'bool'.

choice -- feature used for choice types

choice types provide algebraic sum types of all the generic arguments
provided to choice. A instance of a choice type is a tagged union of
the types provided as actual generic type parameters. This concept is
also called variant, sum type or coproduct in other contexts.

Syntactic sugar of the Fuzion language permits an alternative notation
for choice types with actual generics as follows

A | B | C | ...

which is equivalent to

choice<A, B, C, ...>

The parser will directly convert the first notation into a choice type
with actual generics.

A field of choice type can be assigned a value of the same choice type
or of any of the actual generic type arguments provided to the choice
feature.

Two choice types choice<A,B> and choice<B,A> that differ only in the order
of their actual generic arguments are treated as different types.

Named choice types can be constructed through inheritance, i.e.,

C : choice<A,B> is {}

creates a choice type of A and B with the name C. Two named choice types
D and E that inherit from choice with the same actual generic arguments in
the same order are nevertheless different types and their values are not
assignable to one another.

Named choice types may declare or inherit additional inner features as long
as these features are not fields. Also, declared inner features must not
build a closure that accesses outer features. Additional parents must be
unit types, i.e., they must not declare fields nor access features of any
of their outer features.

Note that all types provided must be distinct, it is not possible to
repeat the same type as in choice<i32,i32> or float | float. If a sum
type of two or more equal types is desired, these types must first be
wrapped into a new type as illustrated in the following example:

Say we want to store a temperature that is given as a 32 bit integer
in degrees centigrade or degrees Fahrenheit. So we define two wrapper
features

centigrade(degrees i32) is {}
fahrenheit(degrees i32) is {}

Now we define the choice type using the wrapped i32 types, which are
distinct:

temp centigrade | fahrenheit := ...

When assigning values to temp, we need to wrap the values accordingly:

set temp := centigrade 37
set temp := fahrenheit 99

When matching the choice type, we use the wrapper types and access the
argument field 'degrees' to access the i32 stored inside

match temp
c centigrade => say "it's " + c.degrees + "°C"
f fahrenheit => say "it's " + f.degrees + "°F"

NYI: Once Fuzion's match statement supports destructuring as well, we should
be able to extract the degrees directly as in

match temp
centigrade d => say "it's " + d + "°C"
fahrenheit d => say "it's " + d + "°F"

A choice type with no actual generic arguments is isomorphic to 'void', i.e, it
is a type that has an empty set of possible values.

codepoint represents a unicode codepoint

codepoints is a unit type defining helper features to work with codepoint

complex -- complex numbers based on arbitrary numeric type

complex provides complex numbers based on a numeric type (e.g. f64, i32).
A complex number consists of a real and an imaginary part.

complex -- returns value of unit type complexes

This is a convenience feature that allows using, e.g.,
'complex<i32>.sum' to get the the monoid of (complex, infix +) instead of
'complexs.sum'.

Since this complex with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with complex with two
arguments).

complexes -- unit type defining features related to complex

complexes is a unit type defining features related to complex but not
requiring an instance.

The plural form of complex is complexes or complices (archaic), according
to https://www.wordhippo.com/what-is/the-plural-of/complex.html, so we
use complexes.

§cons<A, B>(head A, tail B)
 => 
cons<cons.A, cons.B>
:
Cons<A, B>

cons -- feature used to define simple, non-lazy Cons cells

A cons is a cell that contains a head and a tail

Cons -- feature used to define abstract Cons cells

A Cons is a ref to a cell that contains a head and a tail

conststring -- feature used for string constants in Fuzion source code

conststring cannot be called directly, instances are created implicitly by the
backend.

debug is a condition qualifier that enables conditions if debugging is
enabled.

debug(i32) is a condition qualifier that enables conditions if debugging is
enabled at the given debug-level.

Current debug level, used by condition qualified debug(i32)

error represents an error condition described by a message string

NYI: Future versions of error might be equipped with a stack trace if
debugging is enabled

f128 -- 128 bit floating point values

f16 -- 16 bit floating point values

f32 -- 32 bit floating point values


f32 are binary32-numbers as defined in the IEEE 754-2019 standard, see
https://ieeexplore.ieee.org/servlet/opac?punumber=8766227

f32s -- unit type defining features related to f32 but not requiring an
instance


f32 are binary32-numbers as defined in the IEEE 754-2019 standard, see
https://ieeexplore.ieee.org/servlet/opac?punumber=8766227

f64 -- 64 bit floating point values


f64 are binary64-numbers as defined in the IEEE 754-2019 standard, see
https://ieeexplore.ieee.org/servlet/opac?punumber=8766227

f64s -- unit type defining features related to f64 but not requiring an
instance


f64 are binary64-numbers as defined in the IEEE 754-2019 standard, see
https://ieeexplore.ieee.org/servlet/opac?punumber=8766227

boolean value "false"

Note that this value is of unit type >>FALSE<<, not of type >>bool<<, i.e.,
if it is used for type inference as in

myBoolean := FALSE

you will get a variable of type >>FALSE<<, it will not be possible to assign
>>TRUE<< to it. You can use >>false<< as an alternative to get type >>bool<<.

boolean value "false" as a constant of type >>bool<<.

float -- floating point values


float is the abstract parent of concrete floating point features such as
f32 or f64.

floats -- unit type defining features related to float but not requiring
an instance


floats are binary floating point numbers as defined in the IEEE 754-2019
standard, see https://ieeexplore.ieee.org/servlet/opac?punumber=8766227

fraction


fraction provides fraction numbers based on an integer type to represent the
numerator and the denominator.

basic numeric operations +, -, * and comparison are supported. numerator and
denominator are reduced after each operation.

there are currently no checks or preconditions for overflows in the numerator
or the denominator.

fraction -- a convenience routine to create a fraction with den = one


To create a fraction that represents a whole number such as

two := fraction 2 1

you can use this routine with one argument and write

two := fraction 2

Function -- generic function with arbitrary number of arguments and result

fuzion --

handle value created by 'handles.new'

handles provide a means to create handles that refer to update-able
cells.

handles is a one-way state monad. It provides features to create several
handles that refer to modifiable value and features to 'get', 'put' or
'update' this value.

short-hand for creating an empty set of handles of given type.

hasEquals -- feature that allows comparison using 'infix =' operator.

Features inheriting from this feature must be immutable. The operator
'infix =' provides a means to separate values into equivalence classes.

NYI: the compiler should check that features inheriting from this are
actually immutable.

hasHash -- feature for immutable values that have a hash function

NYI: the compiler should check that features inheriting from this are
actually immutable.

hashMap -- an immutable hash map from keys K to values V

hashMap -- convenience routine to create an empty instance of hashMap

hasInterval -- feature for integers that can define an interval

i128 -- 128-bit signed integer values

i128 -- returns value of unit type i128s

This is a convenience feature that allows using, e.g., 'i128.sum' to
get the the monoid of (i128, infix +) instead of 'i128s.sum'.

since this i128 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with i128 with one
argument).

i128s -- unit type defining features related to i128 but not requiring an
instance

i16 -- returns value of unit type i16s

This is a convenience feature that allows using, e.g., 'i16.sum' to
get the the monoid of (i16, infix +) instead of 'i16s.sum'.

since this i16 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with i16 with one
argument).

i16 -- 16-bit signed integer values

i16s -- unit type defining features related to i16 but not requiring an
instance

i32 -- returns value of unit type i32s

This is a convenience feature that allows using, e.g., 'i32.sum' to
get the the monoid of (i32, infix +) instead of 'i32s.sum'.

since this i32 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with i32 with one
argument).

i32 -- 32-bit signed integer values

i32s -- unit type defining features related to i32 but not requiring an
instance

i64 -- returns value of unit type i64s

This is a convenience feature that allows using, e.g., 'i64.sum' to
get the the monoid of (i64, infix +) instead of 'i64s.sum'.

since this i64 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with i64 with one
argument).

i64 -- 64-bit signed integer values

i64s -- unit type defining features related to i64 but not requiring an
instance

i8 -- returns value of unit type i8s

This is a convenience feature that allows using, e.g., 'i8.sum' to
get the the monoid of (i8, infix +) instead of 'i8s.sum'.

since this i8 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with i8 with one
argument).

i8 -- 8-bit signed integer values

i8s -- unit type defining features related to i8 but not requiring an
instance

InitArray -- convenience feature for array creation

NYI: Replace by better syntactic sugar in the Fuzion parser / front end.

int -- signed integer values of arbitrary size

integer


integer is the abstract ancestor of integer numbers that provides operations
from numeric plus a devision remainder operation %, bitwise logical operations,
shift operations and gcd. Also, integers can be used to build fractions.

convenience routine to create a list from head h and lazy tail t.

list -- feature used to define lists

list provides an abstract type for a sequence of elements of the same type.

A list sequence may be empty and contain no element, or it may have a fixed
or even infitie number of elements.

The core of the implementation of an actual list lies in the implementation
of the actual Cons cell a non-empty list consists of.

Lists can typically be traversed using only immutable data. This makes them
more flexible than streams that require to store and update their state.


lists -- unit type defining features related to list but not requiring an
instance

map -- an abstract map from keys K to values V

mapOf -- routine to initialize a map from arrays of ordered elements
and values

This feature creates an instance of a map.

§marray<T>(length i32, init T)
 => 
marray<marray.T>
:
Object

marray -- one-dimensional mutable array

This feature provides a convenient constructor for marray<T>(length,
sys.array<T>, unit).

marray -- one-dimensional mutable array

matrices -- unit type defining features related to matrix

matrices is a unit type defining features related to matrix but not
requiring an instance.

matrix -- matrix based on arbitrary numeric type

matrix provides matrix operations based on an arbitray numeric type

monad -- generic monad

A monad in X is just a monoid in the category of endofunctors of X, with
product × replaced by composition of endofunctors and unit set by the
identity endofunctor.
-- Saunder Mac Lane, Categories for the Working Mathematician, 1971

Don't be scared, in Java terms: A monad is a means to compose functions
applied to generic types.

type related to monad declaring features not requiring an instance of monad

Monoid -- parent feature for monoids

A monoid is an abstraction for a type with an associative operation and
an identity element. Examples are (integers/infix +/0), (float/infix *,1),
(string/concat/""), etc.

nil -- value for options that are not present

This is a unit type that is preferred to represent instances that are
not present, e.g, in an option.

numeric -- parent of all numeric features

numerics -- unit type defining features related to numeric but not
requiring an instance

numOption -- optional numeric values

This is a pseudo-numeric type that handles one additional
value: nil. Any operation on nil will result in nil for a
numeric result or false for a boolean result.

numOption with 1 argument provides an short-hand to wrap a value into a
numOption

Using this enables to write

o := numOption x

insted of

o numOption<TypeOfX> := x

type related to numOption declaring features not requiring an instance of numOption

Object -- parent feature of all features that do not have an explicit parent

option represents an optional value of type T

option with 1 argument provides an short-hand to wrap a value into an option

Using this enables to write

o := option x

insted of

o option<TypeOfX> := x

type related to option declaring features not requiring an instance of option

ordered -- feature for immutable values that have an infix <= function
predicate that defines a total order

features inheriting from ordered define a total order of their values

NYI: the compiler should check that features inheriting from this are
actually immutable.

orderedMap -- an immutable map from ordered keys K to values V

Lookup performance is O(log size) since it uses binary search in a
sorted array. When deterministic performance is desired, an ordered map
should be preferred over a hash map.

performance of creation of the map is in O(n log n) where n is
keys.length.

orderedMap -- convenience routine to create an empty instance of orderedMap

outcome is a choice type that represents the result of a routine that
may either produce something useful or fail producing an error condition.

Several error conditions are needed if there are several very different
reasons for an operation to fail, e.g.

getData (u User, t Type) outcome<data, IOError, PermissionError> is
if u.allowedToAcces T
(readFile t.fileName)?
else
PermissionError u, t

readFile t Type outcome<data, IOError> is
[..]

Note that 'outcome<data, IOError>' is not assignment compatible with
'outcome<data, IOError, PermissionError>', it has to be unwrapped first.
This unwrapping, however, requires very little boilerplate, it is done
using the '?' on the result of the call to 'readFile': This unwraps
'outcome<data, IOError>' into 'IOError', which would be returned abruptly,
and 'data', which would be returned normally. Both are assignment
compatible to 'outcome<data, IOError, PermissionError>', so everything
is fine.

outcome with 1 argument provides an short-hand to wrap a value into a
outcome

Using this enables to write

o := outcome x

insted of

o outcome<TypeOfX> := x

partiallyOrdered -- feature for immutable values that have an infix <=
predicate that defines a partial order

features inheriting from partiallyOrdered define a partial order of their
values

NYI: the compiler should check that features inheriting from this are
actually immutable.

pedantic -- condition qualifier for conditions that are pedantic

pedantic is a condition qualifier for conditions a pedantic purist would require,
but that a more relaxed hacker would prefer to do without.

psMap -- routine to initialize a partially sorted map from two Sequences

This feature creates a pre-initialized instance of psMap.

psMap -- a partially sorted map

psMap is a persistent map from an ordered key K to a value V. This map is
generally well-behaved with respect to cumulative and average performance.

The keys and values are stored in arrays consisting of sorted sub-arrays,
with sub-arrays corresponding to the 1-bits in the binary representation
of the size.

This results in cumulative memory usage in O(size log² size), worst-case
lookup time in O(log² size) and average addition time in O(1) and worst-case
addition time in O(size log² size).

WARNING: Due to the high worst-case time for addition, this structure should
not be used in situations when adding a single element repeatedly to the same
instance of psMap is performance critical. If the resulting map's size n is a
power of 2, this will trigger the worst-case addition time resutling in
O(m*n log² n) for adding an element m times.

This constructor is for internal use only, to create instance of psMap, use
psMap<K,V> without arguments.

psMap -- a partially sorted map

This feature creates an empty instance of psMap.

psSet -- a partially sorted set based on psMap

psSet is a persistent set of ordered values. This set is generally
well-behaved with respect to cumulative and average performance.

WARNING: Due to the high worst-case time for addition, this structure should
not be used in situations when adding a single element repeatedly to the same
instance of psSet is performance critical. If the resulting set's size n is a
power of 2, this will trigger the worst-case addition time resutling in
O(m*n log² n) for adding an element m times.

psSet -- a partially sorted set based on psMap

This feature creates an empty instance of psSet.

psSet -- routine to initialize a partially sorted set from one Sequence

This feature creates a pre-initialized instance of psSet.

quantors provides forAll and exists-quantors for use in contracts qualified
for analysis.

pedantic -- condition qualifier for conditions that are required for safety

safety is a condition qualifier that is used for conditions that are
absolutely required to ensure safety.

This must never be disabled if safety is of any concern. Applications
run with safety disabled typically have security vulnerabilities that
allow system takeover via manipulated input data.

A handy shortcut for stdout.println, output a line break.

A handy shortcut for stdout.println, output string representation of
an object followed by a line break.

searchableList -- a list whose elements inherit from hasEquals

In contrast to searchablelist, this uses ref type 'list' and not choice
type 'list', so it is more flexible.

searchablelist -- a list whose elements inherit from hasEquals

In contrast to searchableList, this uses choice type 'list' and not ref
type 'Sequence', so it is more efficient.

Sequence -- ancestor for features that can be converted to a 'list' or a
'stream'

Sequences are empty, finite or infinite ordered collections of instances
of a given type. Sequences calculate elements lazily on demand.

Sequence is a 'ref' type, i.e., different sub-features may be assigned
to a field of type 'Sequence'.

Heirs of Sequence must implement either 'asList' or 'asStream'. Failure
to implement any of these results in an endless recursion when the Sequence
is used.

Sequences -- unit type defining features related to Sequence but not requiring
an instance

Set -- an abstract set of values V

setOf -- routine to initialize an empty set of ordered elements

This feature creates an instance of a Set.

setOf -- routine to initialize a set from a Sequence of ordered elements

This feature creates an instance of a Set.

some is a standard wrapper for values of type T

sortedarray -- sorted one-dimensional immutable array

This takes an unsorted array and a compare function as an arguments and
returns a sorted one.

Non-mutating heap sort is used internally. This gives guaranteed peformance in
O(n log n) comparisons and assignments for an array of size n.

This is a little wasteful on allocated memory, which is also O(n log n) since
partially sorted arrays are thrown away. This might be improved to use an
in-place heap sort to bring allocated memory down to O(n).

sortedarray -- sorted one-dimensional immutable array of ordered elements

This takes an unsorted array as an argument and returns a sorted one using
the order defined by the type of the elements T.

See sortedArray(from, lessOrEqual) for details

A handy shortcut for stdout.print, output string representation of
an object, do not add a line break at the end.

NYI: there is also 'yak', which I currently prefer, but this needs some
native English speaker's advice.

stream -- a stream of values

NYI: Check if stream should be replaced by a lazy list, which is a choice
of either nil or a tuple (head, tail). This should avoid the need to store
mutable state.

string -- immutable sequences of utf8 encoded unicode characters

strings -- unit type defining features related to string but not
requiring an instance

§sum<U, T>(n U, l Sequence<sum.T>)
 => 
T
:
Object

sum -- generic sum of the elements of a Sequence of numeric.

This allows summing the elements of a list, as in

l := [1,2,3]
say (sum i32 l) # '6'

sum -- generic sum of the elements of a Sequence of numeric.

This allows summing the elements of a list, as in

l := [1,2,3]
say (sum l) # '6'

boolean value "true"

Note that this value is of unit type >>TRUE<<, not of type >>bool<<, i.e.,
if it is used for type inference as in

myBoolean := TRUE

you will get a variable of type >>TRUE<<, it will not be possible to assign
>>FALSE<< to it. You can use >>true<< as an alternative to get type >>bool<<.

boolean value "true" as a constant of type >>bool<<.

§tuple<A...>(values A)
 => 
tuple<tuple.A>
:
Object

tuple -- feature used to define tuple types

tuple types provide algebraic product types of all the generic arguments
provided to tuple.

The values within a tuple 'tuple<A, B, C>' can be accessed via the tuple's
argument field 'values' followed by a selector referring to the generic
argument's position: 'values.0', 'values.1' and 'values.2', respectively.

Syntactic sugar of the Fuzion language permits an alternative notation
to create values of tuple types as follows

t := (a, b, c, ... )

is equivalent to

t := tuple(a, b, c, ... )

The actual generic types are inferred from the static types of the values
'a', 'b', 'c', ... the tuple is created from.

Similarly, syntactic sugar for the destructuring of tuples can be used
to access the values as in

(a, b, c, ...) := t

In destructurings, we can denote values we are not interested in using
'_' as in

(_, b) := ("first", "second")

which will set 'b' to '"second"' and drop the first element of the tuple.

As an example, say we want to identify a person by its name and its age,
so we can define

a := ("Alice" , 11)
b := ("Bob" , 22)
c := ("Claire", 33)

Then, we could extract Bob's age using

(_, age) := b

or Claire's name using

(name, _) := c

Destructuring also works for general features, e.g.

point (x,y i32) is {}

p := point 3, 4
(px, py) := p # will set px to 3 and py to 4

and the destructured value can then be used to create a tuple

t := (px, py) # will create tuple<i32,i32> instance

however, tuples are not assignment compatible with general features even
if they would destructure into the same types, i.e.,

u tuple<i32, i32> = p # will cause compile time error
q point = (7, 12) # will cause compile time error

The unit tuple '()' can be used as a short-hand to create the empty tuple
'tuple<>()'. The empty tuple can be destructured like any other tuple
using

() := ()

even though this has no effect.

An instance of the single tuple 'tuple<A>(a)' can not be created using
syntactic sugar '(a)', this will produce the plain value of 'a' instead.
However, destructuring of a single tuple is possible:

(a0) := tuple<A>(a)

which is equivalent to

a0 := a

NYI: A single tuple 'tuple<A>' is currently not assignment compatible with
type 'A', which would make handling of general tuples easier.

tuples and destructuring can be used to swap two elements or create a
permutation as in

(a, b) := (b, a)
(o, t, a, n) := (n, a, t, o)

A tuple type with no actual generic arguments is isomorphic to 'unit', i.e, it
is a type that has only one single value: '()'.

u128 -- 128-bit unsigned integer values

u128 -- returns value of unit type u128s

This is a convenience feature that allows using, e.g., 'u128.sum' to
get the the monoid of (u128, infix +) instead of 'u128s.sum'.

since this u128 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with u128 with one
argument).

u128s -- unit type defining features related to u128 but not requiring an
instance

u16 -- returns value of unit type u16s

This is a convenience feature that allows using, e.g., 'u16.sum' to
get the the monoid of (u16, infix +) instead of 'u16s.sum'.

since this u16 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with u16 with one
argument).

u16 -- 16-bit unsigned integer values

u16s -- unit type defining features related to u16 but not requiring an
instance

u32 -- returns value of unit type u32s

This is a convenience feature that allows using, e.g., 'u32.sum' to
get the the monoid of (u32, infix +) instead of 'u32s.sum'.

since this u32 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with u32 with one
argument).

u32 -- 32-bit unsigned integer values

u32s -- unit type defining features related to u32 but not requiring an
instance

u64 -- returns value of unit type u64s

This is a convenience feature that allows using, e.g., 'u64.sum' to
get the the monoid of (u64, infix +) instead of 'u64s.sum'.

since this u64 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with u64 with one
argument).

u64 -- 64-bit unsigned integer values

u64s -- unit type defining features related to u64 but not requiring an
instance

u8 -- returns value of unit type u8s

This is a convenience feature that allows using, e.g., 'u8.sum' to
get the the monoid of (u8, infix +) instead of 'u8s.sum'.

since this u8 with no arguments is a routine and not a constructor, it
does not define a type (which would cause a name clash with u8 with one
argument).

u8 -- 8-bit unsigned integer values

u8s -- unit type defining features related to u8 but not requiring an
instance

uint -- unsigned integer values of arbitrary size

unit -- value to be used as result of features that do not return a result

NOTE: unit corresponds to type void in C, Java, etc.

unit is the preferred result type for features that return without producing
a result value. These are features that typically have an outside effect
such as

println(String s) unit is ...

or features that change the state of an instance such as

increment(delta i64) unit is
set counter := counter + delta

The Fuzion language implementation automatically inserts code that returns the
unit value as a result of these features, there is no need for an explicit unit
result as in

increment(delta i64) unit is
set counter := counter + delta
unit

but it is allowed to return unit explicitly if desired.

Another application of the unit type are generic features when certain generic
values are not needed and can be ignored. An example could be a generic map
implementation map<K,V> that maps values of type K to values of type V. Using
unit as the actual generic argument for V, e.g., map<string,unit> creates a
map that stores no data for each key, which essentially turns the map into a
set of the map's keys.

The Fuzion library knows several different unit types. Another example is nil,
which is used as the alternative type in an option. This enables the use of
option<void>, which can store two distinct values, void and nil.

Other unit types in Fuzion are TRUE and FALSE.

The simplest syntax to create a value of unit type is an empty block '{}'. Note
that an empty tuple 'tuple<>' is a different unit value of a different type and
the syntax '()' is (at least for now) not supported.

Please note the fundamental difference between

red is {}
red => {}

The first declares a feature red that defines a new unit type red, the second
declares a feature red with result type unit, i.e., a synonyme for unit as in

red unit is {}

The memory required to store a value of unit type is 0 bits, so you can use
plenty without worrying about space constraints. The Fuzion code generators
typically will not generate any code for returning or assiging a value of unit
type, so these are very efficient as well.

void -- type with no values

NOTE: For a counterpart to void in C, Java, etc., see unit.fz

It is impossible to create any values of this type, consequently, it is impossible
to assign anything to a field of void type.

If used as the type of an argument field for a feature, the feature can never be
called since no value assignable to that argument could ever be produced. This
produces an absurd feature.

If used as the result type of a routine, the routine can never return.

void is the result type of the endless loop

do { <loop body> }

If used as the result type of a field, the field can never be assigned a value,
since no such value can be produced, and the field can never be read since it
remains not initialized forever.

Type void is assignable to all other types, e.g, we can assign void to a value
of type i32:

i i32 := fuzion.std.exit 1

Since no value of type void can ever be produced, the assignment is dead code that
will be removed by the fuzion implementation.

Type void may be used as an actual generic argument for a generic feature. If this
is done, it will turn all features that have arguments of that type into absurd
features. Also, this will ensure that any feature that produces a result of that
type to never return a result (typically to not be callable in the first place as
well). An example could be a stack of capacity zero: stack<void>(0) with an
absurd

stack.push(void)

and a pop function with a precondition that is always false

pop void
pre size > 0

The memory required to store a value of void type is not defined since these
values do not exist. The Fuzion code generators typically will not generate
any code for features receiving arguments of void type or for code following
a feature call that returns void.

wrappingInteger

wrappingInteger is the abstract ancestor of integer numbers that have min and
max values and operations with wrap-around semantics.

wrappingIntegers -- unit type defining features related to wrappingInteger
but not requiring an instance

A handy shortcut for stdout.print, output string representation of
an object, do not add a line break at the end.

The term 'yak' was taken from the expression 'Yakety Yak' as in the
song by The Coasters.