Named functions, lambdas, defaults, variadics, rank-1 generics, static protocol bounds, named arguments, and call spread share one left-to-right call contract.
Policy
A function declares parameter types and an optional result type; its final body expression may return the value. Parameters are immutable. Defaults are literal or const expressions evaluated when omitted and cannot reference another parameter. The final variadic parameter uses ...name: T and receives Array<T>. Lambdas use => and infer concrete parameter types from context. Named function type parameters provide rank-1 polymorphism.
Specified behavior
A call evaluates the callee once, then positional/spread arguments left to right, then binds trailing named arguments. Array spread may contribute only after all fixed parameters and only to a variadic tail. Exact explicit type arguments seed inference before value arguments and expected results; every supplied type must agree. A named generic function may require an order-independent conjunction of admitted static protocols, and its body has exactly those bounds.
Constraints and loud decline
args: ...T, a non-final variadic, positional arguments after named arguments, spread into a fixed parameter, iterable or tuple spread, duplicate/missing arguments, and anonymous function(...) {} expressions are rejected. Bound binders do not exist on lambdas, aliases, nominals, function types, receiver methods, or protocol methods. Partial explicit instantiation, type arguments on monomorphic or unresolved heads, and stronger undeclared bounds are static errors.
Deferred boundary
Higher-rank polymorphism, generic lambdas, variance, default type parameters, generic receiver methods, dynamic protocol dispatch, arbitrary trait constraints, and broad first-class polymorphic values are deferred. Ordinary explicit type arguments erase after checking; only the admitted typed-JSON heads materialize a runtime schema.
Worked example
function head<T>(values: Array<T>) -> Option<T> {
match values {
case [] => None
case [first, ..] => Some(first)
}
}
let first: Option<int> = head([1, 2, 3])