Function Types

Function types consist of the function's parameter types and the function's return type.

The parameter types need to be enclosed in parentheses, followed by a colon (:), and end with the return type. The whole function type needs to be enclosed in parentheses.

// Declare a function named `add`, with the function type `((Int, Int): Int)`.
//
fun add(a: Int, b: Int): Int {
    return a + b
}
// Declare a constant named `add`, with the function type `((Int, Int): Int)`
//
let add: ((Int, Int): Int) =
    fun (a: Int, b: Int): Int {
        return a + b
    }

If the function has no return type, it implicitly has the return type Void.

// Declare a constant named `doNothing`, which is a function
// that takes no parameters and returns nothing.
//
let doNothing: ((): Void) =
    fun () {}

Parentheses also control precedence. For example, a function type ((Int): ((): Int)) is the type for a function which accepts one argument with type Int, and which returns another function, that takes no arguments and returns an Int.

The type [((Int): Int); 2] specifies an array type of two functions, which accept one integer and return one integer.

Argument labels are not part of the function type. This has the advantage that functions with different argument labels, potentially written by different authors are compatible as long as the parameter types and the return type match. It has the disadvantage that function calls to plain function values, cannot accept argument labels.

// Declare a function which takes one argument that has type `Int`.
// The function has type `((Int): Void)`.
//
fun foo1(x: Int) {}

// Call function `foo1`. This requires an argument label.
foo1(x: 1)

// Declare another function which takes one argument that has type `Int`.
// The function also has type `((Int): Void)`.
//
fun foo2(y: Int) {}

// Call function `foo2`. This requires an argument label.
foo2(y: 2)

// Declare a variable which has type `((Int): Void)` and use `foo1`
// as its initial value.
//
var someFoo: ((Int): Void) = foo1

// Call the function assigned to variable `someFoo`.
// This is valid as the function types match.
// This does neither require nor allow argument labels.
//
someFoo(3)

// Assign function `foo2` to variable `someFoo`.
// This is valid as the function types match.
//
someFoo = foo2

// Call the function assigned to variable `someFoo`.
// This does neither require nor allow argument labels.
//
someFoo(4)

Last updated