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.