Skip to content
Sword

Function values

A function named without being called is its own address:

func add(a, b i64) i64 {
return a + b
}
func mul(a, b i64) i64 {
return a * b
}
func apply(op func(i64, i64) i64, a i64, b i64) i64 {
return op(a, b)
}
func main() int {
return int(apply(add, 20, 22))
}

The type is written func(T, U) R, the result omitted when there is none. A parameter the function may write through says mut there too — func(mut []i64) is a different type from func([]i64), because handing over one that writes where the caller expected one that does not would grant permission nobody asked for.

One is a single word, so it sits in a struct or an array without ceremony:

struct Op {
name string
run func(i64, i64) i64
}
func add(a, b i64) i64 {
return a + b
}
func mul(a, b i64) i64 {
return a * b
}
func main() int {
ops := [2]Op{Op{name: "add", run: add}, Op{name: "mul", run: mul}}
mut total i64 = 0
for o in ops {
total += o.run(3, 4)
}
return int(total) + 23
}

There are no closures. A function value is one top-level function and nothing else — it captures nothing, allocates nothing, and has no lifetime to worry about. When a callback needs state to go with it, that is what an interface is for: it carries the state in the pointer.

?func(...) costs one word, with null standing for absence, the same as ?*T. A generic function has no value, because there is no single function to point at.