Control Flow
if, elsif, else
Section titled “if, elsif, else”temperature = 18
if temperature > 25 println "hot"elsif temperature > 15 println "mild"else println "cold"endThe condition can be any value. false, null, 0, 0.0, "", [] and {} are falsy and everything else is truthy; see Truthiness.
if is a statement, not an expression. To choose between values, use a case expression or the ternary operator.
case is an expression: it evaluates to the value of the branch that matches. It comes in two forms.
With a subject, each when is compared to the value after case, like a switch in other languages. A when can list several values separated by commas.
fn describe(day) case day when "Saturday", "Sunday" "weekend" when "Friday" "almost weekend" else "weekday" endend
println describe("Sunday") # weekendprintln describe("Tuesday") # weekdayWithout a subject, each when is a condition, and the first true one wins:
hour = 14
greeting = case when hour < 12 "Good morning" when hour < 18 "Good afternoon" else "Good evening"end
println greeting # Good afternoonIf nothing matches and there is no else, the result is null.
A colon after the when value is optional, and branches can hold several statements. As an expression, a branch evaluates to its last value.
code = 404
case code when 200 println "OK" when 404 println "Not Found" println "Check the URL." else println "Status ${code}"endRanges
Section titled “Ranges”when low..high (or when low to high) matches a value within an inclusive range. No list is built, and the bounds can be floats or negative.
fn grade(score) case score when 90..100: "A" when 80..89: "B" when 70..79: "C" else: "F" endend
println grade(95) # Aprintln grade(72) # Cprintln grade(10) # F
temperature = -5.5println case temperature when -273.15..0.0: "freezing" else: "above freezing"end # freezingwhen guards
Section titled “when guards”Adding when condition to the end of a statement runs it only when the condition is truthy. Guards keep early exits on one line instead of wrapping them in if blocks.
fn safe_divide(a, b) throw "Division by zero" when b == 0 a / bend
for n in [1 to 10] do next when n % 2 == 0 break when n > 7 print "${n} "endprintln "" # 1 3 5 7Guards work on return, throw, break, next, exit, assignments and function or method calls:
fn log(message) println "LOG: ${message}"end
verbose = truelog("starting") when verbose
count = 0count += 1 when verboseprintln count # 1The right-hand side of a guarded assignment is only evaluated when the condition is true, so it is safe to guard an expensive or failing call. If the guard is false the assignment doesn’t happen at all, so a variable that didn’t exist before still doesn’t.
return when condition with no value returns null.
Ternary
Section titled “Ternary”condition ? when_true : when_false is the inline choice between two values:
stock = 3println stock > 0 ? "in stock" : "sold out" # in stockTernaries nest, but a case usually reads better once there are more than two outcomes.
exit code ends the program immediately with that exit code. A bare exit exits with status 0.
config_ok = false
exit 1 when !config_okprintln "never printed"Uncaught errors also end the program, with exit code 1. See Error Handling.
for, while and repeat, along with break and next, are covered in Loops.