Closures are user defined methods which can be saved. They can be used as a prepared piece of code or to consume items from a thing
, list
, tuple
or set
.
They can also be used by procedures.
Closure can be stored in a collection or assigned to a variable.
A closure starts with a |
, then takes optional arguments and a |
to close, followed by a statement.
The most simple closure is ||nil
which is a closure without arguments and returns the value nil
when called.
More complex closures are also possible, check the last example below.
Function | Description |
---|---|
call | Call the closure with optional arguments. |
doc | Return the doc string of the closure. |
Closures may be called recursively up to a recursion depth of 24. If this limit is exceeded, an error is raised.
For example: a = ||a(); a();
…will raise operation_err() (maximum recursion depth exceeded)
Doc strings can be set on closures. This is especially useful when closures are used inside a procedure since this gives the procedure a nice documentation string.
Usually, a doc string is just a normal string on top of a block in the closure.
For example:
|| {
"this is a doc string.";
};
It is common to wrap a block scope within one or more functions. When this is the case, the doc string will be read from the first argument, only if the first non-function argument contains a block scope with a doc string.
For example, this closure contains a block scope wrapped with return and wse:
|| return wse({
"this is still a doc string, even while wrapped using `return` and `wse`.";
}), 2;
This code uses a simple closure together with map and call:
// create a simple closure which just adds one to a given value
add_one = |x| x+1;
// use the closure in a `map` function
map_result = [1, 2, 3].map(add_one);
// use the closure as a function call
call_result = add_one(41);
// return the result values
[map_result, call_result];
Return value in JSON format
[
[
2,
3,
4
],
42
]
Like explained, closures can accept multiple arguments and may contain a block scope instead of just a single line statement. Here is an example:
|name, age| {
"Returns a thing with properties `name`, `age` and `time`.";
assert(is_str(name) && name.len());
assert(is_int(age) && age >= 0);
// this is the last statement so it will be the return value
{
name: name,
age: age,
time: now()
};
};