Functions
- Write [ReturnType] fn name(Type parameter) { body }; the explicit return type comes before fn.
- An omitted return type is inferred only when the function body supplies enough compatible evidence.
- Every reachable path of a value-returning function must return a compatible value.
Function Syntax
1number fn splitAmount(number total, number people) {2 return total / people3}The general form is [ReturnType] fn name[(parameters)] { body }. The function keyword is a lexer alias for fn, but public examples use the shorter canonical form.
Parameters Are Type-First
1string fn expenseLabel(string title, number amount, string? note) {2 string suffix = note ?? ""3 return title + " " + suffix4}- Write
Type name, notname: Type. - Optional parameters use
Type? name. - Arguments are positional and must match the parameter types.
- Parameter names are lowercase locals inside the function body.
Return Inference
1fn balanceLabel(number balance) {2 if balance > 0 {3 return "owed"4 } else if balance < 0 {5 return "owes"6 }78 return "even"9}All value-returning paths produce string, so the function’s effective return type is string. Callers use that inferred signature exactly like an explicit contract.
Implicit Tail Returns
1number fn add(number a, number b) {2 a + b3}A final expression may supply a function’s return value without the return keyword. The expression—or every branch of a final if—must match the declared or inferred return type.
When To Write The Return Type
- Write it when the public contract should be obvious at the declaration.
- Write it when the only returned value is
[],{}, or?and inference has no element type. - Write it when the function is intentionally optional or returns a structural collection.
- Keep it omitted for a small internal helper whose return type is immediate from concrete values.
1Expense[] fn noExpenses() {2 return []3}45Expense? fn noSelectedExpense() {6 return ?7}Complete Return Paths
1string fn statusLabel(bool settled) {2 if settled {3 return "Settled"4 }5 return "Open"6}The incomplete version has a reachable path with no return value and violates its string contract. A throw also terminates a path, so a validated error path does not need a later return.
Calling Functions
1share = splitAmount(expense.amount, member_count)2label = balanceLabel(balance)3clearDraft()Calls always use parentheses. A value-returning call may appear in an expression. A void call is a statement. A trailing effect call is not automatically the function result; write return SomeApi(...) when the call result is the return value.
Common Mistakes
| Wrong | Correct |
|---|---|
fn number splitAmount(...) | number fn splitAmount(...) |
fn splitAmount(total: number) | fn splitAmount(number total) |
def splitAmount | fn splitAmount |
func splitAmount | fn splitAmount |
| Return incompatible types from different paths | Return one compatible type on every value path. |
