Lambda functions
Spice allows you to create lambda functions. Lambda functions are anonymous functions that can be used as values. They are useful for e.g. passing callback functions as parameters into other functions.
Usage¶
Lambdas in Spice work like this:
Procedure lambdas¶
| Spice | |
|---|---|
Function lambdas¶
| Spice | |
|---|---|
Inline lambdas¶
| Spice | |
|---|---|
Capturing lambdas and the Lambda wrapper¶
A lambda that captures variables stores those captures in the stack frame that created it. This is efficient and perfectly safe as long as the lambda does not outlive that frame - for example when it is called immediately or passed to a function that uses it synchronously.
It becomes unsafe when a capturing lambda is kept somewhere that lives longer than the frame that created it, such as a struct field or the return value of a function. To prevent dangling captures, the compiler rejects this:
| Spice | |
|---|---|
To store a capturing lambda, wrap it in the owning Lambda type from std/type/lambda. The wrapper relocates the
captures onto the heap and owns them, so the lambda stays valid for as long as the Lambda object lives. Retrieve
the underlying lambda with get() to call it:
| Spice | |
|---|---|
Lambda values can be copied, assigned and passed around freely. Non-capturing lambdas (plain function pointers)
do not need the wrapper - they are safe to store directly and can be used as field and return types as before.
A Lambda<...> also accepts a non-capturing lambda (it simply owns nothing in that case). This makes Lambda a
good fit for a field or parameter that should accept any routine, capturing or not - for example the routine
passed to std/os/thread's Thread, which may capture or not depending on the caller.