Functions with funcra
Typed user-defined functions are implemented in Scarp v0.0.5-alpha.1. The keyword is funcra, not fn, func, or function. Parameters and result types are mandatory. Local bindings still infer types.
Declaration and calls
funcra square(value: integer) -> integer {
return value * value;
}
bind answer = square(6);
print(answer); // 36
Non-unit functions must return the declared kind along every path. A unit function may use bare return; or fall through; a unit result is not usable as an expression value. Forward calls, recursion, and mutual recursion within a file are supported.
Optional and named arguments
funcra endpoint(start: integer, length: integer = 5) -> integer {
return start + length;
}
print(endpoint(7), endpoint(length: 2, start: 10));
Output is 12 12 with a newline. Required parameters precede optional ones; named arguments can be provided in any order after positional arguments. Defaults evaluate for omitted arguments and may refer to earlier parameters.
Purity and contracts
pure funcra clipped(x: integer, lo: integer = 0, hi: integer = 10) -> integer
needs lo <= hi;
ensures result >= lo and result <= hi;
{
if x < lo { return lo; }
if x > hi { return hi; }
return x;
}
print(clipped(x: 15)); // 10
pure is checked: a pure function cannot produce output or call impure user functions. needs clauses are runtime preconditions; ensures clauses are runtime postconditions. They are executable checks, not formal proofs. A postcondition can reference result for non-unit functions.
Call limits and restrictions
The interpreter uses heap call frames, not unbounded host-stack recursion. Depth and cumulative call counts have configurable limits. No overloads, generics, closures, variadic user functions, or implicit access to top-level script locals are implemented. See budgets and source modules.
Verified against: functions reference, tested functions fixture, contract fixture.