Core syntax Functions

Functions

Top-level functions use the def keyword. They may declare typed parameters, default values, overloads, recursive behavior, explicit return types, and exception contracts.

Basic Declaration
def add(a as Int, b as Int) as Int:
    return a + b
Parameter Passing

Input parameters use value passing by default. Add readonly when the function must not reassign its local parameter binding, and use out when the function must write a result back into the caller's variable.

def copy(readonly source as Int, out destination as Int):
    # source = 0               # Compile-time error: source is read-only.
    destination = source

input = 42
result = 0
copy(input, result)
assert result == 42

An out argument must be an addressable variable with exactly the declared static type; a literal, temporary expression, or implicit numeric conversion cannot provide the required storage. Output parameters require an explicit type and cannot be variadic or have a default value. The callee cannot read an out parameter before assigning it and must assign it on every normal exit. Because that assignment is mandatory, readonly out is invalid. notnull expresses an input precondition, so notnull out is invalid as well. readonly does not make the referenced object deeply immutable; it only prevents reassignment of an input parameter binding. The in keyword remains the collection-membership operator and the separator in for loops, but it is not a parameter qualifier.

Updating a Visible Variable

An ordinary assignment inside a function updates an existing visible variable, including a mutable variable declared at module scope. It does not implicitly create a local copy of that global variable. The variable keeps its declared or inferred static type.

counter as Int = 0

def increment():
    counter += 1

increment()
assert counter == 1

Parameters and explicitly declared local variables have their own bindings. If no variable with the assigned name is visible, the first assignment introduces one in the current block. See Typing for the assignment and scope rules.

Default Arguments
def greet(name as String = "World") as String:
    return "Hello, " + name
Overloading
def add(a as Int, b as Int) as Int:
    return a + b

def add(a as Double, b as Double) as Double:
    return a + b

Overloads are resolved by parameter types, so explicit typing is especially important here.

Variadic Parameters

Place ... after a parameter name to collect positional or named arguments. The dedicated Variadic Parameters page explains both forms, their static types, declaration order, and overload resolution.

def sumAll(values ... as Int) as Int:
    total as Int = 0
    for value in values:
        total += value
    return total

assert sumAll() == 0
assert sumAll(10, 20, 30) == 60
Returning Multiple Values
def powers(n as Int):
    return n, n ** 2, n ** 3

result = powers(10)
a, b, c = powers(10)

Returning multiple comma-separated values produces a positional Tuple<...Ts> that can be stored or unpacked.

Recursion
def fact(n as ULong) as ULong:
    return 1 if n == 0 else n * fact(n - 1)
Functions and Exceptions

Functions may raise exceptions as part of their normal implementation. Public APIs on types also commonly declare explicit throws clauses. The detailed exception model is covered in Exceptions and Resource Safety.

Functions Are Not Methods
Keep the two declaration styles separate

Top-level functions use def. Methods declared inside a class body do not. Inside a class you write declarations such as public compute() as Int: directly.