Options
Option types
An option can be empty or contain a single value.
An option type is written as foo? .
() returns an empty option.
Any value can implicitly convert to a non-empty option containing it.
So any nat can implicitly convert to a nat? .
Options are useful for functions that might not have a result:
"if" and options
Options implicitly convert to bool.
If you test an option in an if condition, then inside the if body,
it will implicitly convert to its (non-optional) inner value.
The below example uses first from the standard library,
which returns the first element in an array if one exists.
The local can be introduced inside the if.
As with if, if the left side of an and expression is an option,
it is implicitly converted to a non-option on the right side.
You can even introduce a local in the left side of an and expression.
You can also test record fields. This won't work on mutable fields.
It also works with any function with an immutable argument.
Option operations
! is a suffix operator that forces an option.
This gets the inner value or throws an exception if the option is empty.
If the ! comes after a function name as in half! 4,
it forces the function's return value.
a or b is analogous to the boolean or.
It first evaluates a. If that is a non-empty option, it is returned.
Otherwise, it evaluates b.
In other words, a or b or ... evaluates options in sequence
and returns the first non-empty one.
a else b is like a or b, but expects b to be non-optional.
While a or b takes two options of the same type, a else b only takes an option on the left.
So the else expression is non-optional, since it always has b to fall back on.
Optional calls
?foo calls foo if all of its arguments are non-empty options.
Otherwise it skips the call and returns an empty option.
?foo can also return void if that is the expected type.
This also works with dot-calls: x.?foo
It works for subscript calls too:
Useful option functions
from-option converts an option to any collection.