Functions¶
Aside from built-in methods and functions, RCL supports user-defined functions.
let add = (x, y) => x + y;
// Evaluates to 42.
add(22, 20)
Functions are first-class: they are values that can be assigned to variables and passed to other functions. Functions are anonymous: the name you use to call them is not an inherent property of the function, but of the variable that it is assigned to. Functions are closures: the function body can reference variables defined outside of the body. Such functions are sometimes called lambda functions or lambdas in other languages.
Defining functions¶
A =>
arrow creates a function, with the arguments on the left and the body on the right.
let sub = (x, y) => x - y;
// Evaluates to 42.
sub(50, 8)
A trailing comma in the argument list is optional.
let sub = (
x,
y,
) => x - y;
When a function takes a single argument, the parentheses may be omitted.
let double_input = x => x * 2;
Closures¶
A function can capture variables defined outside the function body. The names remain bound to the values they had when the function was defined. If a later let-binding shadows an earlier one, this does not affect the function.
let x = 42;
let get_x = () => x;
let x = 0;
// Evaluates to 42, not to 0, because x was bound to 42 when get_x was defined.
get_x()
Variables in RCL bind names to immutable values, not to mutable memory locations. This means that in a loop, functions capture the value that a variable has in that iteration of the loop.
let fs = [for k in [1, 2, 3]: x => x * k];
// Evaluates to [10, 20, 30].
[for f in fs: f(10)]
First-class functions¶
Functions are values and can be passed to functions:
let apply_twice = (f, x) => f(f(x));
// Evaluates to 256 = (4 * 4) * (4 * 4);
apply_twice(x => x * x, 4)
This is useful with built-in methods such as List.group_by
.
let replicants = [
{ activation_year = 2016, name = "Pris Stratton" },
{ activation_year = 2016, name = "Roy Batty" },
{ activation_year = 2017, name = "Leon Kowalski" },
];
replicants.group_by(r => r.activation_year)
// Evaluates to:
{
2016: [
{ activation_year = 2016, name = "Pris Stratton" },
{ activation_year = 2016, name = "Roy Batty" },
],
2017: [
{ activation_year = 2017, name = "Leon Kowalski" },
],
}