Functions

8.1 Basics

Arguments are immutable by default. Functions can be declared in any order (no forward declarations needed). There's no function overloading and no default arguments (use struct parameters instead; see 8.5).

fn add(x int, y int) int {
	return x + y
}

fn greet(name string) {
	println('Hello, ${name}')
}

fn sub(x int, y int) int { return x - y }

8.2 Multiple Return Values

fn divmod(a int, b int) (int, int) {
	return a / b, a % b
}
q, r := divmod(17, 5)
_, rem := divmod(9, 4)        // ignore with _

8.3 Mutable Arguments

fn double_all(mut arr []int) {
	for i in 0 .. arr.len { arr[i] *= 2 }
}
mut nums := [1, 2, 3]
double_all(mut nums)          // `mut` required at the call site too

8.4 Variadic Functions

fn sum(nums ...int) int {
	mut total := 0
	for n in nums { total += n }
	return total
}
println(sum(1, 2, 3))
arr := [4, 5]
println(sum(...arr))          // spread an array

8.5 Trailing Struct Arguments (Named and Default Parameters)

@[params]
struct ButtonConfig {
	text    string
	width   int = 100
	height  int = 30
	enabled bool = true
}

fn new_button(c ButtonConfig) {
	println('${c.text} ${c.width}x${c.height}')
}

new_button(text: 'OK')                     // the struct literal can be written inline
new_button(text: 'Cancel', width: 200)
new_button()                               // allowed with @[params]: all defaults

8.6 Functions as Values

fn square(x int) int { return x * x }
fn apply(f fn (int) int, v int) int { return f(v) }
println(apply(square, 5))

type Op = fn (int, int) int
fn run(op Op) int { return op(2, 3) }
println(run(fn (a int, b int) int { return a * b }))

8.7 Visibility

Use pub fn to export from a module. Everything is private by default.

8.8 Recursion and Pure-Function Style

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