Functions

Declaration

Functions are declared with fn. Parameter and return-type annotations are optional but recommended:

fn greet(name: string): string {
    return "Hello, " + name + "!"
}

fn add(a, b) {          // annotations omitted
    return a + b
}

A function with no return type returns void. return with no value, or falling off the end, returns void.

Anonymous functions & closures

Functions are first-class values. Write an anonymous function with fn(...) and assign it, pass it, or return it. Closures capture variables from the enclosing scope:

let double = fn(x) { return x * 2 }
println(double(21))      // 42

fn makeAdder(n: int) {
    return fn(x) { return x + n }    // captures n
}
let add10 = makeAdder(10)
println(add10(5))        // 15

This is the form you pass to array methods and to APIs like thread.core.spawn:

let evens = [1, 2, 3, 4].filter(fn(n) { return n % 2 == 0 })

Variadic parameters & spread

A final parameter prefixed with ... collects any extra arguments into an array:

fn sum(...nums) {
    let total = 0
    for n in nums {
        total += n
    }
    return total
}

println(sum(1, 2, 3, 4))   // 10

The ... spread operator also expands an array into positional arguments at a call site:

let args = [1, 2, 3]
println(sum(...args))      // 10

Hoisting & recursion

Top-level function declarations are hoisted, so a function can be called before it appears in the file, which also makes mutual recursion straightforward:

println(fib(10))         // works — fib is defined below

fn fib(n: int): int {
    if n <= 1 {
        return n
    }
    return fib(n - 1) + fib(n - 2)
}

Functions can also be nested inside other functions.

Notes

  • There are no default or named parameters — pass every argument positionally (or use a variadic / an object).
  • Functions return a single value; to return several, return an array or object.

Continue to value methods for the methods available on strings, arrays, and numbers.