Functions
Declaring functions
In Veila, functions begin with a #, followed by a parenthesized list of
parameters:
# (a, b) a + b + 3
This is an anonymous function that returns the sum of a, b, and 3.
The function body can be written on multiple indented lines. The last expression is the return value.
# (a, b)
c ← a + b
c + 2
The parameter and return types can be specified:
# (a: integer, b: integer): integer
a + b + 3
Functions are given names the same way other values are:
plus-two ← # (a, b)
c ← a + b
c + 2
Aliases
To help with typing, functions whose names contain Unicode characters may also have an alias, which follows the standard name in parentheses. For example, multiplication is defined as:
× (*) ← #([n: numerical], [n] → [n]) #external
The formatter will replace occurrences of * with × where applicable. Note:
It’s possible for multiple functions to share the same alias, as long as the
function type makes it unambiguous.
Calling functions
To call a function, place the arguments after the function name. When a function accepts only one parameter, the parenthesis can be omitted:
f 2
g(1, 2)
Binary functions can be infixed; in fact, the mathematical operators are just regular functions:
1 + 2 – Equivalent to +(1, 2)
As a result, an expression with multiple elements will evaluate from left to right:
1 + 2 * 3 / 4 – Equivalent to (((1 + 2) * 3) / 4)
As demonstrated above, terms are left-associative, and all functions have the same precedence.
Named parameters
Arguments can be named when calling functions:
times ← # (number, factor) number × factor
3 times (factor: 4) – 12
It’s possible to give an external label to parameters, which will be used by the caller to label the arguments. In this case, the label is required:
times ← # (number, by factor) number × factor
3 times (by: 4) – 12
– won't compile: 3 times 4
An underscore as the label denotes that the parameter name is the label name:
times ← # (number, _ factor) number × factor
3 times (factor: 4) – 12
Named arguments allow a function with parameters that differ only in name:
greet ← # (to person) print-line “Hello, ‘person’!”
greet ⥆ # (from person) print-line “Greetings from ‘person’!”
greet(to: “Revi”) – Hello, Revi!
greet(from: “Livi”) – Greetings from Livi!
This is how the built-in range function works:
range(1, <: 5) – 1, 2, 3, 4
range(1, =: 5) – 1, 2, 3, 4, 5