Skip to content

Control Flow

if temperature > 30 {
io::print("It's hot!")
} else if temperature < 10 {
io::print("It's cold!")
} else {
io::print("Nice weather!")
}

Conditions must be boolean expressions. There are no implicit truthy/falsy coercions.

let fruits = ["apple", "banana", "cherry"]
for fruit, index in fruits {
io::print("{index}: {fruit}")
}

The index cursor can be omitted in list loops

let fruits = ["apple", "banana", "cherry"]
for fruit in fruits {
io::print(fruit)
}
let scores: [Str:Int] = ["Alice": 95, "Bob": 87, "Carol": 92]
for name, score in scores {
io::print("{name} scored {score.to_str()}")
}
// Inclusive range
for i in 1..10 {
io::print(i)
}
// With step (if supported)
for i in 0..100 step 10 {
io::print(i) // Prints 0, 10, 20, ..., 100
}
for mut i = 0; i <= 5; i =+ 1 {
io::print("Count: {i}")
}
mut count = 0
while count < 10 {
io::print("Count is {count}")
count =+ 1
}

Match expressions are similar to switch expressions in most languages.

When ranges overlap, the first match wins:

let grade = match score {
0 => "How?",
1..59 => "F",
60..69 => "D",
70..79 => "C",
80..89 => "B",
90..100 => "A",
_ => "Invalid score"
}
let response = match is_valid {
true => "Proceed"
false => "Error: invalid input"
}
enum Status { active, inactive, pending }
let message = match user_status {
Status::active => "Welcome back!"
Status::inactive => "Please reactivate account"
Status::pending => "Account under review"
}

Use match expressions to handle different types in a union:

type Content = Str | Int | Bool
fn describe(value: Content) Str {
match value {
Str => "Text: {it}"
Int => "Number: {it.to_str()}"
Bool => "Flag: {it.to_str()}"
}
}
let items: [Content] = ["hello", 42, true]
for item in items {
io::print(describe(item))
}

Patterns are evaluated in the order they appear. More specific patterns should come before general ones:

Ard supports the break keyword for early termination of loops.

for item in items {
if should_skip(item) {
break
}
process(item)
}