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.