Lambdas
Lambda expressions
A lambda expression consists of:
- The
ofkeyword - A destructuring; the same syntax as for locals
- An indented block
subscript calls the lambda.
An optional return type annotation goes after of.
A lambda can be squeezed onto one line using then.
Lambda parameters
All lambdas take a single parameter.
If nothing is written after the of, it means the parameter is void.
As with locals, comma-separated names destructure a single tuple parameter.
Lambda types
A lambda type consists of:
- The return type
- The mutability (
data,shared, ormut) - A destructuring in parentheses.
This syntax is used for the type of f below:
If the lambda expression (of x above) has an expected type,
it doesn't need to re-declare the parameter type (nat).
Mutability
The code in a lambda can access and even modify variables outside the lambda. This is called a closure.
There are different kinds of lambdas for different mutability levels.
(See Mutability.)
The closure of a lambda affects its mutability:
- A
mutlambda has no restrictions. This is the default for lambdas with an inferred type. - A
sharedlambda can only haveshared(ordata) types in its closure.
It can't referencemutlocals (even just to read them) regardless of their type. - A
datalambda can only havedatatypes in its closure.
It also can't call anyglobalfunctions. (See Global side effects.)
Most lambdas are mut when there is no need to restrict them.
shared lambdas are used in parallel code. (See Parallelism.)
data lambdas are rarely used,
but may be useful in situations where the lambda must be stateless.
For example, a comparator lambda used for sorting might be data.
"it"
There is a shorthand syntax for simple lambdas.
The tightly-packed expression containing the it keyword is the body of a lambda.
Expressions that work in an it lambda are:
- Dotted function calls:
it.is-even - Prefix operators:
-it - Binary operators:
it*2 subscriptcalls:it[0]- Type annotations:
it::nat - Option forcing:
it!
The it lambda can contain any number of these simple operations:
… though the above is just to prove a point and would be more readable as an of lambda.
Most expressions can not be written as an it lambda.
is-multiple-of it, 2 would not work,
because that looks like the first argument of is-multiple-of is a lambda.
it is intended for simple expressions; for other cases, use an of lambda.
An it lambda must contain at least one operation.
For an identity lambda, use identity.
"new" interfaces
Defining an interface implicitly defines a new function
that takes lambdas corresponding to each interface method.
"with" blocks
Many functions that take a lambda do some preparation, call the lambda once, and then return.
To make that intention clear, there is a with keyword providing a syntax for it.
with blocks provide a syntax to make that intention clear.
A common use of with is to build a collection using build.
The above is equivalent to calling
with-block build, of out ...
A type annotation on the with keyword applies to the return type of with-block.
A with-block function can be defined like so:
It's not unusual to define a type whose only purpose is to be the first argument to with-block.
log-start-and-end above is an example.