if / else
Like most languages, Roc has if and else keywords that determine which code to runs based on a boolean's value at runtime.
if and else
Roc's if keyword is syntax sugar for match. This code:
if foo {
bar()
} else {
baz()
}
Does the exact same thing as this code:
match foo {
True => bar()
False => baz()
}
Roc does not have a concept of "truthiness" (where values can be "truthy" or "falsy"); if accepts only Bool values.
else if
Roc does not have a separate else if concept like some languages do, but you can write else followed immediately by if to achieve that functionality. This code...
if foo {
bar()
} else {
if something {
baz()
} else {
blah()
}
}
...does exactly the same as this code, without the extra curly braces:
if foo {
bar()
} else if something {
baz()
} else {
blah()
}
if without else
You write an if without an else, but only when the body of the if evaluates to {}. For example, this is allowed:
if foo {
do_something!()
}
It is essentially equivalent to:
{} = if foo {
do_something!()
} else {
{}
}
...except that you don't have write the {} = or the else. The rules are the same, though; the body of the if must evaluate to {}, which in practice only makes sense for effectful functions, or statements like return, crash, or expect.
and / or
The keywords and and or perform short-circuiting evaluation by desugaring to if:
a() or b()
...desugars to:
if a() True else b()
Similarly:
a() and b()
...desugars to:
if a() b() else False
The desugared versions compile to the same machine instructions as the operator versions, even in debug builds.
Note that Roc does not have && or || keywords for boolean logic like some languages do. This is mostly because Roc uses | to define functions, and || means a function with no arguments. Using the keyword or avoids overloading || to mean a function sometimes and a conditional other times.