Overview
In MUFL the convention is to treat containers as functions, consequently, MUFL has three flavors of functional types:
- Reduceable - functions, represented by the
->
syntax. - Mutable - dictionaries, represented by the
->>
syntax. Mutable types, by definition, are both scannable and reduceable. - Scannable - types that can be iterated over using the
scan
statement, represented by the*>
syntax.
Reduceable Types
Reduceable types are those which may be used in a reduction expression a b
. These are functions and dictionaries (also strings and binaries). Reduceable types are represented by type expression reducer->product
, where the reducer
is the type of argument in the reduction expression and product
is the type of the result of the reduction expression.
Example:
ToString = fn a:int = (_str a).
IntToStrFunc is int->str = ToString. // compatible because ToString takes int and returns str
ResultFor10 is str = IntToStrFunc 10. // compatible because product is of type str
Functional type operations are right-associative, so to declare a function of three arguments using this syntax you use the expression
arg1->arg2->arg3->ret
.
Scannable Types
Scannable types refer to those types that can be used in a scan
statement. They are represented by the *>
type expression.
For example, the INTEGER_SEQUENCE
domain maps to the scannable type int*>int
. Integer sequences are scannable, but not reduceable.
Mutable Types
Mutable types refer to dictionaries and are represented by type expression reducer->>product
. Mutability implies reduceability, so a->b
is compatible with a->>b
but not vice versa. Similarly, mutability implies scannability.
Mutable types indicate a value to which the mutation operator ->
can be applied.