Skip to content

Function Pointer Types

Overview

Function pointer types represent references to functions. A function pointer value can be called using the same syntax as a function call. Function pointer types are not capabilities and MAY be stored in struct members and returned from functions.

Syntax

// function pointer type: ReturnType(Param1Type, Param2Type)
int(int, int)

// function pointer type with no return value
(int, int)

// function pointer type with no parameters
int()

// function pointer type with no parameters and no return value
()

// assigning a function to a variable (type is inferred)
let add = someFunction;

// calling a function pointer
add(1, 2);

// function accepting a function pointer as a parameter
function useCallback(callback: int(int, int)): int {
    return callback(1, 2);
}

Rules

Function Pointer Type Syntax

A function pointer type MUST be written as ReturnType(Param1Type, Param2Type, ...). The return type MUST appear before the parameter list. If the function returns no value, the return type prefix MUST be omitted, leaving only the parenthesized parameter list (Param1Type, ...). If the function takes no parameters, the parameter list MUST be empty ().

Type Constructor Precedence

In type expressions, the handle type constructors (& for struct handles, [] for slice handles) bind more tightly than the function pointer type constructor (T()). &int(int) MUST NOT be valid; & only applies to struct types and int is not a struct type.

// function pointer returning []int, taking int
[]int(int)    == ([]int)(int)

// slice of function pointers (parens required)
[](int(int))

// function pointer returning &Point, taking int
&Point(int)   == (&Point)(int)

// INVALID: &int is not a valid type (no handles to primitives)
// &int(int)

If a function pointer's return type contains a handle type, the return type MUST NOT require parentheses. Parentheses MUST be used to express a handle of function pointer types.

Function Pointer Values

A bare function name used in an expression context MUST evaluate to a function pointer value for that function. The type of the function pointer value MUST match the function's signature. The type MUST be inferred when a function is assigned to a variable.

Calling Function Pointers

A function pointer value MUST be callable using the pointerName(args) syntax, identical to regular function call syntax. The arguments MUST match the function pointer's parameter types. The call MUST produce the function pointer's return type.

Storage

Function pointer types MUST be permitted as struct member types. Function pointer types MUST be permitted as function parameter types and return types. Function pointer types MUST NOT be implicitly converted.

Capabilities in Function Pointers

Capability types (read T, write T) MUST be permitted as parameter types and in function pointer types, capability types MUST NOT be permitted as return types in function pointer types.

Comparison

Function pointer values MUST be comparable using the == and != operators. Two function pointers MUST be equal if they reference the same function.

Representation

A function pointer MUST be represented as a 64-bit pointer to the function's entry point.

Memory Safety

Function pointers MUST NOT capture local state; Larol does not support closures. Capability parameters in function pointer types MUST be scoped to the duration of the call; the compiler MUST enforce that capabilities are valid at the point of the call.