Functions
Function declaration grammar is given in Declarations.
Instance-method promotion
Section titled “Instance-method promotion”A function whose first parameter is an E#-declared data (value or *T) is promoted to a method on
that type. Promotion is by-attachment across files; it does not apply to choice, enum, primitives, or
external/C# types.
The call shape depends on the receiver kind:
| Receiver | Free call f(x) | Method call x.f() | In method set of |
|---|---|---|---|
value func f(x: T) | ill-formed — ES2142 | required | T and *T |
pointer func f(x: *T) | valid | valid | *T only |
A value-receiver method has no static host: it is reachable wherever its receiver type is in scope,
regardless of declaring namespace. A pointer-receiver function remains a namespace-scoped free function
that also joins *T’s method set. A function with a readonly *T first parameter is not promoted (a
value-type this is always mutable).
returns clause
Section titled “returns clause”ReturnType = ( "->" | "returns" ) Type .ReturnsClause = "returns" Type . // class-level, inside ref data / static funcreturns T is a synonym for -> T in a signature. As a standalone clause inside a ref data or
static func body it sets the default return type for member functions that omit their own
annotation; an explicit -> T on a member overrides it.
Method chaining
Section titled “Method chaining”A promoted call chains when a method returns a value the next call lands on. A method returning its
receiver yields a fluent API; for a ref data this returns the same instance (mutation threads through),
for a value data a fresh value each step. A chain may break across lines with a leading dot — a
newline before . continues the chain. A method returning Result<T, E> does not chain; unwrap each step
with ?.
Lambdas and closures
Section titled “Lambdas and closures”Lambda = "func" "(" [ ParamList ] ")" [ ReturnType ] ( Block | "=" Expr ) | "(" [ identifier { "," identifier } ] ")" "=>" Expr .A function literal closes over the enclosing scope. Captures are mutable — a write inside the closure is
visible outside and vice versa; a closure over a let binding may read but not assign it (compiler-
enforced). Arrow-lambda parameter types are inferred when a delegate type is expected at the call site.
Captured variables are hoisted into a generated display class shared by the outer scope and all closures
over those captures.
Function pointers
Section titled “Function pointers”FuncPtrType = "&" "(" [ TypeList "->" ] Type ")" . // &(int, int -> int) , &(string -> void) , &(-> bool)&f takes a function’s address — zero allocation, single-target, emitted as ldftn + calli. A
function-pointer type is first-class (struct fields, parameters, locals). The binder verifies signature
compatibility at the call site. Function pointers are the systems tier; heap-allocated, multicast
delegates are the interop tier — see Delegates & events. The disambiguation
between &f (function pointer) and &x (address-of a variable) is by what the name resolves to; see
Pointers & by-ref.