Control Flow in Kiwi¶
Kiwi offers a compact but very expressive set of control structures.
Truthiness¶
A condition is any boolean expression. Non-boolean values are also valid — they are coerced to a boolean based on whether they are truthy or falsy:
| Type | Truthy example | Falsy example | Rule |
|---|---|---|---|
integer |
1 |
0 |
Non-zero is truthy |
float |
1.0 |
0.0 |
Non-zero is truthy |
boolean |
true |
false |
The boolean values |
string |
"hello" |
"" |
Non-empty string is truthy |
list |
[1, 2, 3] |
[] |
Non-empty list is truthy |
hashmap |
{"a": 1} |
{} |
Non-empty hashmap is truthy |
Quick Reference¶
| Construct | Best for | Returns value? | Early-exit friendly? |
|---|---|---|---|
if / elsif / else |
Classic branching | No | Somewhat |
case … when … else |
Matching one value or many conditions | Yes | Yes |
when guard clauses |
Early returns, skips, errors | — | Yes |
?: ternary |
Inline single-condition choice | Yes | No |
break / next when … |
Loop control | — | Yes |
1. if – elsif – else¶
Traditional conditional blocks.
if user.age < 18
println "Access denied"
elsif user.banned
println "Account suspended"
else
grant_access(user)
end
2. case – when – else¶
Two common styles:
A. Condition-only case (when conditions are unrelated)¶
hour = time::now().hour()
time_of_day = case
when hour.between(5, 11) 'morning'
when hour.between(12, 16) 'afternoon'
when hour.between(17, 21) 'evening'
else 'night'
end
B. Value-tested case (similar to a switch statement in other languages)¶
greeting = case time_of_day
when 'morning' 'Good morning!'
when 'afternoon' 'Good afternoon.'
when 'evening' 'Good evening.'
when 'night' 'Hello, night owl!'
else 'What time is it again?'
end
C. Multiple values per when (comma-separated)¶
A when clause can match against multiple values by separating them with commas. The branch fires if the test value equals any of them.
mood = case day
when "Monday" "Here we go again."
when "Friday" "Almost there!"
when "Saturday", "Sunday" "Enjoy the weekend!"
else "Just another day."
end
This also works in condition-only case:
D. Ranges in when¶
Use start..end (or start to end) in a when clause to match a numeric range. Both bounds are inclusive. No list is allocated — the check is O(1).
fn letter_grade(score)
return case score
when 90..100: "A"
when 80..89: "B"
when 70..79: "C"
when 60..69: "D"
else: "F"
end
end
println letter_grade(95) # A
println letter_grade(72) # C
println letter_grade(50) # F
Ranges can be mixed freely with literal values and comma-separated lists in the same case:
fn classify(n)
return case n
when 0: "zero"
when 1..9: "single digit"
when 10..99: "double digit"
else: "big"
end
end
fn day_type(d)
return case d
when 1..5: "weekday"
when 6, 7: "weekend"
else: "invalid"
end
end
Ranges also work with floats and negative bounds:
result = case temp
when -273.15..0.0: "below freezing"
when 0.0..100.0: "liquid"
else: "steam or beyond"
end
3. when – Guard clauses / conditional modifiers¶
Append when condition to many statements for clean early exits.
fn safe_divide(a, b)
throw "Division by zero" when b == 0
return a / b
end
for file in files do
next when exclusions.contains(file)
process(file)
end
exit 1 when !config.valid
Supported with:
- return … when …
- throw … when …
- break when …
- next when …
- exit … when …
- x = expr when … and x += expr when … (all assignment forms)
- bare method/function calls: some_fn() when …
Not meaningful on a bare expression whose value is discarded — the expression evaluates to a value but nothing uses it, so the when guard has no observable effect:
If you want to conditionally execute something, use a method call or an assignment:
log(x + 1) when flag # ✓ call with side-effect
result = x + 1 when flag # ✓ assignment (result is null if condition is false)
Lazy evaluation for assignments: the right-hand side expression is only evaluated when the condition is true. This means it is safe to guard against expensive or potentially failing calls:
4. Ternary operator ?:¶
Inline if-else expression.
status = file.exists() ? "found" : "not found"
price_display = discount > 0 ? "${price * (1 - discount)}" : price
Related topics¶
- Loop-specific controls:
break,next,while,for,repeat - Function exit:
return - Error raising:
throw - Program termination:
exit