Documentation Index
Fetch the complete documentation index at: https://soul-lang.com/llms.txt
Use this file to discover all available pages before exploring further.
for_in
The for...in loop is the most idiomatic way to iterate over collections in Soul. It provides a clean syntax for iterating through lists, maps, and other iterable objects without managing indices manually.
Basic For-In with Lists
Iterate through list elements:
fruits = ["apple", "banana", "cherry", "date"]
for (fruit in fruits) {
println("Fruit: " + fruit)
}
// Output: apple, banana, cherry, date
For-In with Maps
Iterate through map key-value pairs:
user = {
"name": "Alice",
"age": 30,
"city": "New York"
}
for (key, value in user) {
println(key + ": " + value)
}
// Output: name: Alice, age: 30, city: New York
For-In with Key Only (Maps)
Iterate through map keys only:
config = {
"debug": true,
"timeout": 5000,
"retries": 3
}
for (key in config) {
println("Setting: " + key + " = " + config[key])
}
For-In with Value Only (Lists)
The standard pattern for lists:
numbers = [1, 2, 3, 4, 5]
for (num in numbers) {
result = num * 2
println("Double: " + result)
}
For-In with Index and Value
Some collections may provide both index and value:
items = ["first", "second", "third"]
for (index, item in items) {
println("Index " + index + ": " + item)
}
For-In with Nested Collections
Iterate through nested data structures:
users = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 35}
]
for (user in users) {
println("User: " + user.name + " (Age: " + user.age + ")")
}
For-In with String Characters
Iterate through string characters:
text = "Hello"
for (char in text) {
println("Character: " + char)
}
// Output: H, e, l, l, o
For-In with Break and Continue
Control loop execution:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for (num in numbers) {
if (num == 5) {
break // Exit when number is 5
}
if (num % 2 == 0) {
continue // Skip even numbers
}
println("Odd number: " + num)
}
// Output: 1, 3
For-In with Complex Data
Process complex data structures:
orders = [
{"id": 1, "customer": "Alice", "total": 150.00},
{"id": 2, "customer": "Bob", "total": 75.50},
{"id": 3, "customer": "Charlie", "total": 200.00}
]
totalRevenue = 0
for (order in orders) {
totalRevenue += order.total
println("Order " + order.id + ": $" + order.total)
}
println("Total Revenue: $" + totalRevenue)
For-In with Filtering
Filter elements during iteration:
products = [
{"name": "Laptop", "price": 999, "category": "Electronics"},
{"name": "Book", "price": 15, "category": "Literature"},
{"name": "Phone", "price": 599, "category": "Electronics"}
]
for (product in products) {
if (product.category == "Electronics") {
println("Electronic: " + product.name + " - $" + product.price)
}
}
Transform data during iteration:
names = ["alice", "bob", "charlie"]
capitalizedNames = []
for (name in names) {
capitalizedName = name.toUpperCase()
capitalizedNames.push(capitalizedName)
}
for (name in capitalizedNames) {
println("Capitalized: " + name)
}
For-In with Function Calls
Call functions for each element:
soul processUser(user) {
return "Processed: " + user.name + " (" + user.email + ")"
}
users = [
{"name": "Alice", "email": "alice@example.com"},
{"name": "Bob", "email": "bob@example.com"}
]
for (user in users) {
result = processUser(user)
println(result)
}
For-In with Maps and Complex Keys
Iterate through maps with complex structures:
cache = {
"user:123": {"name": "Alice", "lastSeen": "2023-01-01"},
"user:456": {"name": "Bob", "lastSeen": "2023-01-02"},
"user:789": {"name": "Charlie", "lastSeen": "2023-01-03"}
}
for (key, userData in cache) {
println("Key: " + key)
println("User: " + userData.name + " (Last seen: " + userData.lastSeen + ")")
}
For-In with Nested Loops
Nested for-in loops for multi-dimensional data:
departments = {
"Engineering": ["Alice", "Bob", "Charlie"],
"Marketing": ["Dave", "Eve"],
"Sales": ["Frank", "Grace", "Henry"]
}
for (department, employees in departments) {
println("Department: " + department)
for (employee in employees) {
println(" Employee: " + employee)
}
}
For-In with Error Handling
Handle errors during iteration:
urls = ["http://example1.com", "http://example2.com", "invalid-url"]
for (url in urls) {
try {
response = fetchData(url)
println("Success: " + url)
} catch (error) {
println("Error with " + url + ": " + error)
}
}
For-In with Conditional Logic
Complex conditional processing:
students = [
{"name": "Alice", "grade": 85, "subject": "Math"},
{"name": "Bob", "grade": 92, "subject": "Science"},
{"name": "Charlie", "grade": 78, "subject": "Math"}
]
for (student in students) {
if (student.subject == "Math" && student.grade >= 80) {
println("Honor student: " + student.name + " (Grade: " + student.grade + ")")
}
}
For-In with Accumulation
Accumulate values during iteration:
expenses = [
{"category": "Food", "amount": 50},
{"category": "Transport", "amount": 30},
{"category": "Food", "amount": 25},
{"category": "Entertainment", "amount": 40}
]
categoryTotals = {}
for (expense in expenses) {
category = expense.category
amount = expense.amount
if (categoryTotals[category] == null) {
categoryTotals[category] = 0
}
categoryTotals[category] += amount
}
for (category, total in categoryTotals) {
println(category + ": $" + total)
}
Optimize for-in loop performance:
// Cache expensive operations outside the loop
items = getItems()
processor = createProcessor()
for (item in items) {
processor.process(item) // Reuse processor
}
// Avoid creating objects in loops
for (item in items) {
// Good - reuse variables
result = processItem(item)
// Avoid - creates new object each iteration
// config = {"setting": "value"}
}
Best Practices
- Use for-in for collections: It’s more readable than index-based loops
- Use meaningful variable names:
user instead of u
- Handle null/undefined: Check for valid data before processing
- Use break/continue appropriately: Control flow when needed
// Good - clear and safe
soul processValidUsers(users) {
if (users == null) {
return
}
for (user in users) {
if (user == null || !user.isActive) {
continue
}
processUser(user)
}
}
// Better - with error handling
soul processValidUsers(users) {
if (users == null || users.length() == 0) {
return
}
for (user in users) {
try {
if (user != null && user.isActive) {
processUser(user)
}
} catch (error) {
println("Error processing user: " + error)
}
}
}
The for...in loop is the preferred way to iterate over collections in Soul, providing clean, readable code that’s less error-prone than manual index management.