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

choice

🌌choice

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.