Functions and Closures
Kelvra already supports named functions, block function literals, expression-bodied lambdas, recursion, and closures with captured variables.
Named functions
Section titled “Named functions”fn add(left i32, right i32) i32 { return left + right}Named functions and methods can omit an explicit void return type:
fn logAnswer() { print(42)}Function types
Section titled “Function types”Function types appear directly in signatures and local bindings.
fn applyTwice(f fn(i32) i32, value i32) i32 { return f(f(value))}var addOne fn(i32) i32 = fn(x i32) => x + 1Lambdas
Section titled “Lambdas”Expression-bodied lambdas are the compact form:
var addOne = fn(x i32) => x + 1Block function literals are available when you want multiple statements:
var addOne fn(i32) i32 = fn(x) { return x + 1}Parameter types still matter. The repo includes negative tests for missing parameter annotations and return-type mismatches.
Closures
Section titled “Closures”Nested functions can capture outer locals.
fn makeAdder(base i32) fn(i32) i32 { return fn(delta i32) => base + delta}
var addTen = makeAdder(10)print(addTen(32))The test suite also covers closure mutation and deeper nested upvalue chains, so captured state is not limited to the simplest read-only case.
Recursion
Section titled “Recursion”Named functions can call themselves normally. Several stress tests in the repo exercise recursive execution.
Return rules
Section titled “Return rules”Kelvra’s type checker enforces return behavior:
- returned values must match the declared return type
- named functions without a value should omit the return type or use
void - omitted return values on non-
voidpaths are errors