Functions and closures in Edva are first-class values with uniform 16-byte representation and full static type inference.
Signatures, types, and runtime ABI
| Multi-arg signature |
f: Int, String => <> |
Declared on the line preceding f = a, b => body (E2009 if combined inline) |
| Zero-arg signature |
f: () => Int |
Defined with f = !=> body and invoked with postfix f! |
| Void return signature |
f: String => () |
Returns Unit (void in LLVM IR) |
| Nested function type |
#type Cb (Int => Int)
apply: (Int => Int), Int => Int |
Wrap function types in parentheses (...) when inside records, containers, or parameter lists |
| Runtime representation |
{ ptr fn_ptr, ptr env_ptr } (16 bytes) |
fn_ptr: machine code pointer; env_ptr: arena-allocated capture struct pointer (null for non-capturing functions). Zero RTTI or vtables |
Closures, lexical capture, and returns
| Lexical capture |
make_adder = base => (n => base + n) |
Captures outer bindings into an arena-allocated environment struct (env_ptr) |
| Tail return |
Final expression in body |
Evaluates as the function’s return value |
| Valued early return |
--| expr |
Immediately exits enclosing function with expr (E3084 on return type mismatch) |
| Void early return |
Bare --| |
Immediately exits a () => () void function |
| Ram return sugars |
c |->, c |+>, c |-->, c |++> |
When c is <+>, early-returns <->, <+>, <-->, or <++> |
#use io
make_Downloads: Int => (Int => Int)
make_Downloads = factor =>
x =>
x < 0 | --| 0
x * factor
scale5 = make_Downloads(5)
io::out $ (scale5(4), scale5(-2)) // (20, 0)
Invocation and pipeline operators
| Direct call |
f(a, b) |
Postfix (LBP 170, left) |
Direct invocation (no space before (, E2032) |
| Nullary call |
f! |
Postfix (LBP 170, left) |
Invokes 0-argument function f |
| Feed pipeline |
x $> f / x $> f(a) |
Feed (LBP 40, RBP 50, left) |
Prepends x as first argument: f(x) / f(x, a) |
| Infix apply |
f $ x / f(a) $ b |
Apply (LBP 30, RBP 30, right) |
Appends x / b as last argument: f(x) / f(a, b) |
| Block apply |
f $ + indented k = v block |
Apply (LBP 30, RBP 30, right) |
Passes indented key-value block as a single record argument |
| Monadic bind |
ram $>> cont |
Feed (LBP 40, RBP 50, left) |
Unwraps positive ram slot into ram-returning cont; short-circuits negative slot (E3091) |
Audience: Edva developers
Status: current reference
Audited: 51081a6
Evidence: src/codegen/types.dva, src/codegen/expr.dva,
GRAMMAR.md