Skip to content

Lambda

Spice
import "std/type/lambda";

Lambda<S> struct

Lambda is an owning wrapper around a native lambda value.

A native lambda is a fat pointer with the layout { fctPtr, capturePtr, captureSize }. When a lambda captures more than a single inline value, its captures live in a dedicated capture struct that the compiler stack-allocates in the frame that created the lambda. That is fine as long as the lambda does not outlive that frame, but it is unsound to store such a lambda somewhere that lives longer (e.g. a struct field).

Therefore native lambda types are not allowed as field, return or element types. To persist a lambda, wrap it in a Lambda: the wrapper copies the capture struct onto the heap and takes ownership of it, so the wrapped lambda stays valid for as long as the Lambda object lives and can be passed around and stored arbitrarily.

The captures are relocated with a raw byte copy, which matches the way the compiler builds the capture struct (a shallow copy of the captured values). The capture size travels inside the fat pointer, so a Lambda can take ownership of any native lambda, regardless of where it was created.

Retrieve the underlying native lambda via get() to call it:
Lambda()> wrapped = Lambda()>(f() { return 42; });
f() native = wrapped.get();
int result = native();

Note: once Spice supports overloading the call operator, get() can be complemented by an operator() that simply forwards to it, without changing the storage model.

Constructors

ctor

Spice
public p Lambda.ctor()

Construct an empty Lambda that owns no captures. Calling get() on an empty Lambda yields an unspecified native lambda, so an empty Lambda must be assigned a wrapped lambda before it is used.

ctor

Spice
public p Lambda.ctor(S lambda)

Wrap a native lambda, taking ownership of its captures by relocating the capture struct onto the heap.

Parameters

Name Type Description
lambda S

ctor

Spice
public p Lambda.ctor(const Lambda<S>& original)

Copy-construct a Lambda, deep-copying the owned capture struct so that both instances own independent storage.

Parameters

Name Type Description
original const Lambda<S>&

dtor

Spice
public p Lambda.dtor()

Release the owned capture struct (if any).

Methods

get

Spice
public inline f<S> Lambda.get()

Return the wrapped native lambda. Its capturePtr points into this Lambda's owned storage, so the returned value is valid for as long as this Lambda is alive.

Returns: S

isEmpty

Spice
public inline f<bool> Lambda.isEmpty()

Returns true if the lambda is empty

Returns: bool

Operators

operator=

Spice
public p operator=<S>(Lambda<S>& this, const Lambda<S>& original)

Deep-copy assignment. Releases the currently owned capture struct first.

Parameters

Name Type Description
original const Lambda<S>&