Conditional Statements
If / Else
The basic conditional structure in Soul:
score = 85
if ( score >= 90 ) {
print ( "Grade: A" )
} else if ( score >= 80 ) {
print ( "Grade: B" )
} else if ( score >= 70 ) {
print ( "Grade: C" )
} else {
print ( "Grade: F" )
}
Truthiness
Soul follows these rules for truthiness:
Falsy Values
false
null
0
""
(empty string)
Truthy Values
true
Any non-zero number
Any non-empty string
Lists and Maps (even empty)
Functions
// Examples
if ( 0 ) { } // Won't execute
if ( "" ) { } // Won't execute
if ([]) { } // Will execute (empty list is truthy)
if ({}) { } // Will execute (empty map is truthy)
if ( "false" ) { } // Will execute (non-empty string)
Ternary Operator
For simple conditions, use the ternary operator:
age = 18
status = age >= 18 ? "adult" : "minor"
// Can be nested (but use sparingly)
grade = score >= 90 ? "A" : score >= 80 ? "B" : "C"
Switch Statements
For multiple conditions on the same value:
day = "Monday"
switch ( day ) {
case "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" :
print ( "Weekday" )
break
case "Saturday" , "Sunday" :
print ( "Weekend" )
break
default :
print ( "Invalid day" )
}
Soul requires explicit break
statements to prevent fall-through between cases.
Loops
While Loop
Executes while a condition is true:
count = 0
while ( count < 5 ) {
print ( "Count: " + count )
count = count + 1
}
// Infinite loop with break
while ( true ) {
input = console . read ()
if ( input == "quit" ) break
print ( "You said: " + input )
}
For Loop
Traditional C-style for loop:
// Basic for loop
for ( i = 0 ; i < 10 ; i = i + 1 ) {
print ( i )
}
// Multiple variables
for ( i = 0 , j = 10 ; i < j ; i = i + 1 , j = j - 1 ) {
print ( i + ", " + j )
}
// Can omit parts
i = 0
for (; i < 5 ; ) {
print ( i )
i = i + 1
}
For-In Loop
The most idiomatic way to iterate in Soul:
Iterating Lists
fruits = [ "apple" , "banana" , "orange" ]
// Simple iteration
for ( fruit in fruits ) {
print ( fruit )
}
// With index using range
for ( i in 0. . fruits . length () - 1 ) {
print ( i + ": " + fruits [ i ])
}
Iterating Maps
person = {
"name" : "Alice" ,
"age" : 30 ,
"city" : "New York"
}
// Iterate keys only
for ( key in person ) {
print ( key + ": " + person [ key ])
}
// Iterate key-value pairs
for ( key , value in person ) {
print ( key + " = " + value )
}
Range Iteration
// Inclusive range (0 to 4)
for ( i in 0..4 ) {
print ( i ) // 0, 1, 2, 3, 4
}
// Can use variables
start = 5
end = 10
for ( n in start .. end ) {
print ( n )
}
Loop Control
Break
Exit a loop early:
for ( i in 0..100 ) {
if ( i * i > 50 ) {
break // Exit the loop
}
print ( i )
}
// Breaking nested loops
for ( i in 0..3 ) {
for ( j in 0..3 ) {
if ( i == j ) break // Only breaks inner loop
print ( i + "," + j )
}
}
Continue
Skip to the next iteration:
// Print only even numbers
for ( i in 0..10 ) {
if ( i % 2 == 1 ) {
continue // Skip odd numbers
}
print ( i )
}
// Process valid items only
items = [ 1 , null , 3 , null , 5 ]
for ( item in items ) {
if ( item == null ) continue
print ( "Processing: " + item )
}
Error Handling
Try / Catch
Handle errors gracefully:
try {
// Risky operation
result = riskyFunction ()
print ( "Success: " + result )
} catch ( error ) {
print ( "Error occurred: " + error )
}
// Can throw custom errors
soul divide ( a , b ) {
if ( b == 0 ) {
throw ( "Division by zero!" )
}
return a / b
}
try {
result = divide ( 10 , 0 )
} catch ( e ) {
print ( "Caught: " + e ) // "Caught: Division by zero!"
}
Finally Block
Execute code regardless of success or failure:
file = null
try {
file = io . open ( "data.txt" )
data = file . read ()
process ( data )
} catch ( e ) {
print ( "Error: " + e )
} finally {
// Always runs
if ( file ) {
file . close ()
}
}
Pattern Examples
Early Return Pattern
soul validateUser ( user ) {
if ( ! user ) return false
if ( ! user . email ) return false
if ( ! user . age || user . age < 18 ) return false
return true
}
Guard Clauses
soul processOrder ( order ) {
// Guard clauses first
if ( ! order ) {
print ( "No order provided" )
return
}
if ( order . items . length () == 0 ) {
print ( "Order has no items" )
return
}
// Main logic here
processItems ( order . items )
}
Loop with Index and Value
items = [ "first" , "second" , "third" ]
// Manual index tracking
i = 0
for ( item in items ) {
print ( i + ": " + item )
i = i + 1
}
// Or use range
for ( i in 0. . items . length () - 1 ) {
print ( i + ": " + items [ i ])
}