Functions and calls¶
Function signatures describe parameter types and results. Callers may bind parameters positionally or by name without changing the meaning of the call.
Design documentation
This chapter describes the language design. Examples are illustrative; implementation availability and unresolved rules are explained in Design status.
Reading a signature¶
In fun add(x: int, y: int) -> int, fun introduces the function,
x and y name its parameters, and -> int describes its result. The
body uses braces and return supplies the result. Local bindings can infer
their type from an initializer; public APIs expose their types and contracts.
let total = add(y=2, x=1) // Binds x to 1 and y to 2.
add(1, x=2) // Error: x is bound twice.
Keyword order can change evaluation order even when the resulting parameter bindings are equivalent. Expressions are always evaluated in their written order before the canonical binding is used by tracing or caching.
Source and call rules¶
- UTF-8 source and Unicode support are required.
- Examples use
fun, braces, type annotations, and local type inference. - Public APIs expose signatures and contracts explicitly.
- Every argument can be supplied positionally or by keyword.
- Argument expressions evaluate in source order.
- Duplicate bindings of the same parameter are errors.
- After binding, calls have one canonical argument representation.
fun add(x: int, y: int) -> int {
return x + y
}
add(1, 2)
add(x=1, y=2)
add(1, y=2)
These calls bind the same parameter values, which matters for inspection, mocks, tracing, and caching. Omission remains distinguishable from explicitly supplying a value when parameter-specific sentinels are involved.
Arguments are read-only unless marked mut. A reassignable binding and permission
to mutate the object it references are separate concepts. The working convention
is let for non-reassignable bindings and var for reassignable bindings; the
complete declaration and borrowing syntax remains provisional.