Callables
Callables are function values. They are Thread-Stack-managed: referencing a function allocates its frame on the heap and stores a pointer to the function in front of it.
The fn Type
// no params, no return
fn<() -> void>
// two params, one return
fn<i32, i32 -> i32>
// multiple returns: no parens
fn<i32, i32 -> i32, i32>
Special-case notations:
// params only, no return (-> void omitted)
fn<i32>
// neither params nor return
fn<>
Function References
def greet():
print("Hello, World!\n");
def main():
// '::' is the reference operator
fn<() -> void> g = ::greet;
g();
Coremodule andexternfunctions cannot be referenced (::printis an error).- Callables are freed/overwritten on reassignment; copying a callable clones its frame.
Callables as Values
Pass, return, and mutate callables like any value:
def apply_op(fn<i32, i32 -> i32> op, i32 x, i32 y) -> i32:
return op(x, y);
def get_sub() -> fn<i32, i32 -> i32>:
return ::sub;
// callables pass by reference
def set_sub(mut fn<i32, i32 -> i32> op):
op = ::sub;
def main():
fn<i32, i32 -> i32> op = get_sub();
i32 res = apply_op(op, 20, 10);
set_sub(op);
res = apply_op(op, res, 5);
Persistent Locals
persistent keeps local state across calls; per callable instance, not static/shared:
def counter() -> i32:
persistent i32 c = 0;
// '++' not usable in expression contexts yet
i32 current = c;
c++;
return current;
def main():
fn<() -> i32> c1 = ::counter;
fn<() -> i32> c2 = ::counter;
c1(); // 0
c1(); // 1
c2(); // 0
- Cannot combine
persistentwithconst. - Direct calls (
counter()) reset the state each invocation; only callable instances persist.
Use cases: counters, rate-limiters (with Core.time), state machines, accumulators.
Error Sets in Callables
// possible errors in the fn type
fn<bool {ErrAssert}> f = ::may_fail;
f(true) catch err:
switch err:
ErrAssert(e): print($"ErrAssert = {e}\n");
anyerror(e): print($"anyerror = {e}\n");
An unspecified error set expands to {anyerror}:
// This expands to the type fn<bool -> void {anyerror}>
fn<bool> f = ::may_fail;
so any function reference can be stored regardless of the errors it may throw.