Control Flow
Currently there is only one control flow construct: the if expression:
if expression
As usual for all functional programming languages all control flow constructs
are expressions instead of statements and therefore always return a value. This
is not different for Arena. The knowledge
acquired in previous chapters combined with an if expression suffices to calculate the 40th fibonacci number:
fn main() = fib(40)
fn fib(n: i32) -> i32 =
if n < 1 then
n
else
fib(n-1) + fib(n-2)
If either the then or the else block include an expression with a semicolon
you have to surround the block with curly brackets to resolve possible
ambiguities of the location of the end of the block.
Alternatively you can use the fact, that in Arenaparanthesis can include any
expression. This allows you to surround the block that includes a semicolon with
paranthesis instead of surrounding both with curly brackets.
Round brackets in general and curly brackets specifically for if expressions can also always be added precautisouly.
fn print_n_times(str: String, n: i32) =
if n <= 1 then
print(str)
else {
print(str);
print_n_times(str, n-1)
}
// Or:
fn print_n_times(str: String, n: i32) =
if n <= 1 then
print(str)
else (
print(str);
print_n_times(str, n-1)
)
// Or:
fn print_n_times(str: String, n: i32) =
if n <= 1 then {
print(str)
} else {
print(str);
print_n_times(str, n-1)
}
match expression
The match keyword also starts an expression and is mainly used to deconstruct
user defined types. Each match expression takes an object and tries to match
it against a set of patterns. The body of the first pattern that succeeds will
be executed populating the variables defined in the pattern with the
corresponding values. This example shows how a spaced print could be implemented for
a linked list of words.
type List {
Nil,
Cons(String, List),
}
fn printList(l: List) =
match l {
List.Nil => print("\n"),
List.Cons(w, List.Nil) => print(w); print("\n"),
List.Cons(w, tail) => print(w); print(" "); printList(tail),
}