Control Flow
Conditionals, loops, and flow control statements in Soli.
If/Else Statements
if / else / elsif
Conditional branching statements.
age = 18
# Simple if
if age >= 18
print("Adult")
end
# If-else
score = 75
if score >= 60
print("Pass")
else
print("Fail")
end
# Else-if chain
grade = 85
if grade >= 90
letter = "A"
elsif grade >= 80
letter = "B"
elsif grade >= 70
letter = "C"
elsif grade >= 60
letter = "D"
else
letter = "F"
end
print(letter); # "B"
Unless
unless / end
Runs the body when the condition is falsy — the inverse of if.
This is a real statement, not a rewrite of if !cond, so
unless a || b keeps that meaning.
unless user.admin?
halt(403, "Forbidden")
end
# else is allowed; elsif is not
unless cart.empty?
checkout()
else
redirect("/cart")
end
# short bodies still format as postfix
return cached unless cached.nil?
Optional then works the same as on if:
unless ready then wait() end.
The then Keyword
then
The then keyword is an optional separator between the condition and the body of an if, elsif, or unless statement.
It improves readability, especially for single-line conditionals.
# Multi-line with then
if age >= 18 then
print("Adult")
end
# Single-line with then
if user != null then print("Welcome, " + user.name) end
# Works with elsif too
x = 42
if x > 100 then
print("big")
elsif x > 10 then
print("medium")
else
print("small")
end
# Parentheses and then can be combined
if (score >= 90) then
grade = "A"
end
# Without then (also valid)
if age >= 18
print("Adult")
end
Note: then is purely syntactic sugar. Both if condition then ... end and if condition ... end are equivalent.
Parentheses around the condition are also optional.
While Loops
while
Repeats while a condition is true.
i = 0
while i < 5
print("Count: " + str(i))
i = i + 1
end
# Output: Count: 0, 1, 2, 3, 4
For Loops
for ... in
Iterates over collections or ranges.
# Iterate over array
fruits = ["apple", "banana", "cherry"]
for fruit in fruits
print(fruit)
end
# Iterate with range
for i in range(0, 5)
print(i); # 0, 1, 2, 3, 4
end
# Range with step
for i in range(0, 10, 2)
print(i); # 0, 2, 4, 6, 8
end
# Nested loops
for i in range(1, 4)
for j in range(1, 4)
print(str(i) + " x " + str(j) + " = " + str(i * j))
end
end
Postfix Conditionals
if / unless
Ruby-style postfix conditionals for concise one-liners.
x = 10
print("big") if x > 5
y = 3
print("small") unless y > 5
status = "active"
print("Welcome!") if status == "active"
print("Account locked") unless status != "banned"
Ternary Operator
condition ? true_value : false_value
Inline conditional expression.
x = 10
size = x > 5 ? "large" : "small"
print(size); # "large"
# Nested ternary
grade = 85
letter = grade >= 90 ? "A"
: grade >= 80 ? "B"
: grade >= 70 ? "C"
: grade >= 60 ? "D"
: "F"
print(letter); # "B"
Exiting and Skipping Iterations
break
Exits the innermost enclosing loop immediately. Works in while and for loops, and supports postfix conditions.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for n in numbers
break if n > 7
print(n)
end
# prints: 1, 2, 3, 4, 5, 6, 7
# Do-while equivalent: infinite `while` + `break`
count = 0
while true
count = count + 1
break unless count < 3
end
print(count); # 3
break propagates out of nested blocks, if branches and try/catch — a finally block still runs before the loop exits. A break inside a lambda or function body does not break an outer loop; it is absorbed at the function boundary.
for path in paths
try
contents = File.read(path)
if contents.blank?
break # exits the for loop, not just the if/try
end
catch error
break # `finally` still runs first
finally
print("checked #{path}")
end
end
next
Skips to the next iteration of the loop.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sum = 0
for n in numbers
if n % 2 == 0
next
end
sum = sum + n
end
print("Sum of odd numbers: " + str(sum)); # 1+3+5+7+9 = 25