5.1.13. Blocks
This tutorial covers block declarations, passing blocks to functions,
the pipe <| operator, simplified => syntax, call syntax, and
invoke() for local block variables.
5.1.13.1. Declaring a block
Blocks are anonymous functions prefixed with $():
var blk = $(a, b : int) => a + b
print("{invoke(blk, 3, 4)}\n") // 7
5.1.13.2. Blocks as function arguments
Use block in the parameter type. Inside the function, call blocks
directly — just like regular functions:
def do_twice(action : block) {
action() // call syntax — preferred
action()
}
With typed parameters and return:
def apply_to(value : int; transform : block<(x:int):int>) : int {
return transform(value) // call syntax, not invoke
}
5.1.13.3. The pipe operator
Use <| to pass a trailing block argument:
do_twice() {
print("hello!\n")
}
5.1.13.4. Simplified blocks
When a block has a single expression body, use =>:
let result = apply_to(5, $(x) => x * x) // 25
5.1.13.5. Call syntax vs invoke
Inside a function that receives a block parameter, use call syntax:
def filter(arr : array<int>; predicate : block<(x:int):bool>) {
for (v in arr) {
if (predicate(v)) { // call syntax: predicate(v)
print("{v} ")
}
}
}
For local block variables, use invoke():
var blk = $(a, b : int) => a + b
print("{invoke(blk, 3, 4)}\n")
5.1.13.6. Capture rules
Blocks capture outer variables by reference and are stack-allocated. They cannot be stored in containers or returned from functions — use lambdas for that.
Next tutorial: Lambdas and Closures