Function application

A function application f a1 a2 an applies the function f to the arguments a1 through an.

The above syntax is valid where f is a regular identifier. If the function name is an operator such as *, then the syntax for application is infix : a1 * a2. Any operator can be used in prefix position by surrounding it in parentheses: (*) a1 a2.

All Unison functions are of arity 1. That is, they take exactly one argument. An n-ary function is modeled either as a unary function that returns a further function (a partially applied function) which accepts the rest of the arguments, or as a unary function that accepts a tuple.

Function application associates to the left, so the expression f a b is the same as (f a) b. If f has type T1 -> T2 -> Tn then f a is well typed only if a has type T1. The type of f a is then T2 -> Tn. The type constructor of function types, ->, associates to the right. So T1 -> T2 -> Tn parenthesizes as T1 -> (T2 -> TN).

The evaluation semantics of function application is applicative order Call-by-Value. In the expression f x y, x and y are fully evaluated in left-to-right order, then f is fully evaluated, then x and y are substituted into the body of f, and lastly the body is evaluated.

An exception to the evaluation semantics is Boolean expressions, which have non-strict semantics.

Unison supports proper tail calls so function calls in tail position do not grow the call stack.