6. Functions
function_definition = "fn" , NAME , "(" , [ parameter_list ] , ")" , block ;
parameter_list = NAME , { "," , NAME } , [ "," ] ;
6.1 Definition and binding
fn name(params): defines a function and binds name in the current scope when
the definition statement executes. A function defined inside another function is
bound in that call's scope and is not visible outside it.
fn square(n):
return n * n
print(square(9))
# => 81
6.2 Parameters and arity
Parameters are positional. A call must pass exactly as many arguments as the
function has parameters, otherwise E0303. There are no default
values, variadic parameters, or keyword arguments in Milestone 1. A trailing
comma is allowed in both the parameter list and the argument list.
6.3 Return value
return expr ends the call with expr's value. return with nothing, and
falling off the end of the body, both yield nil. return outside any function
is E0201, reported before the program runs.
fn first_even(xs):
for x in xs:
if x % 2 == 0:
return x
return nil
print(first_even([1, 3, 4, 7]))
print(first_even([1, 3, 5]))
# => 4
# => nil
6.4 Functions are values
A function is an ordinary value: it can be stored, passed, and returned.
type() reports "function" for user functions and builtins alike.
fn apply_twice(f, x):
return f(f(x))
fn inc(n):
return n + 1
print(apply_twice(inc, 10))
# => 12
6.5 Closures
A function captures the scope in which it was defined. It sees, and can modify, variables from enclosing functions by the nearest-binding rule (ADR 0011).
fn make_adder(n):
fn add(x):
return x + n
return add
add5 = make_adder(5)
print(add5(1))
print(add5(100))
# => 6
# => 105
The capture is by binding, not by value, so a closure that assigns to a captured variable changes it for every other closure over the same binding:
fn counter():
count = 0
fn tick():
count = count + 1
return count
return tick
t = counter()
print(t())
print(t())
# => 1
# => 2
6.6 Recursion
A function may call itself. Call nesting is bounded (see §10.5);
unbounded recursion is reported as E0313 rather than crashing.