Iterators
functional helpers for easier block iteration (loops, filtering, mapping, etc)
Functions
Predicates
The Iterators module provides functional programming tools for working with collections. From simple loops to complex transformations, it offers a consistent way to process collections with elegant, expressive code.
Key Concepts
- Collection iteration with various strategies
- Functional transformations (map, filter, fold)
- Collection analysis (every?, some?, enumerate)
- Consistent behavior across all collection types
- Support for block-based predicate conditions
Basic Usage
Looping Through Collections
numbers: [1 2 3 4 5]
; basic iteration
loop numbers 'n ->
print ["Number:" n]
; Number: 1
; Number: 2
; Number: 3
; Number: 4
; Number: 5
; with index
loop.with:'i numbers 'n ->
print ["Item" i ":" n]
; Item 0 : 1
; Item 1 : 2
; Item 2 : 3
; Item 3 : 4
; Item 4 : 5
; dictionary iteration
user: #[name: "John" age: 30]
loop user [key value]->
print [key "->" value]
; name -> John
; age -> 30
Note
Iterator functions work uniformly with all collection types:
- Blocks:
loop [1 2 3] 'x [...]
- Dictionaries:
loop #[a:1 b:2] [k v] [...]
- Strings:
loop "hello" 'c [...]
- Ranges:
loop 1..5 'x [...]
- Numbers:
loop 3 'i [...]
(equivalent to1..3
)
Transforming Collections
numbers: 1..5
; transform each element
doubled: map numbers 'x -> x * 2
print doubled ; 2 4 6 8 10
; using the => shorthand for simple transformations
squared: map numbers => [& ^ 2]
print squared ; 1 4 9 16 25
; chaining transformations
result: map numbers 'x ->
(to :string x) ++ "!"
; ["1!" "2!" "3!" "4!" "5!"]
Filtering Elements
numbers: 1..10
; keep elements matching condition
evens: select numbers 'n -> even? n
print evens ; 2 4 6 8 10
; remove elements matching condition
noEvens: filter numbers 'n -> even? n
print noEvens ; 1 3 5 7 9
; shorthand for simple predicates
odds: select numbers => odd?
print odds ; 1 3 5 7 9
Common Patterns
Testing Collections
numbers: [2 4 6 8]
; check if all elements match
every? numbers => even? ; => true
; check if any element matches
some? numbers => [& > 10] ; => false
; count matching elements
enumerate numbers 'x -> x > 5 ; => 3
Collecting and Grouping
data: ["apple" "banana" "apricot" "cherry"]
; group by first letter
byLetter: gather data 'word -> first word
print byLetter
; [a:[apple apricot] b:[banana] c:[cherry]]
; collect elements while condition is true
ascending: collect [1 2 3 2 4 5] 'x ->
x < 4
print ascending ; 1 2 3 2
Advanced Transformations
; fold (reduce) a collection
sum: fold 1..5 [acc val]->
acc + val
; 15
; with seed value
sumFrom100: fold.seed:100 1..5 [acc val]->
acc + val
; 115
; arrange (sort) with custom predicate
users: @[
#[name: "John" score: 42]
#[name: "Alice" score: 28]
#[name: "Bob" score: 35]
]
sorted: arrange users 'user -> user\score
print.lines map sorted 'u -> u\name
; Alice
; Bob
; John
Tip
The arrow operator (=>
) is particularly useful with iterators for creating concise, readable code. For example:map nums => [& * 2]
instead ofmap nums 'x -> x * 2
Working with Nested Data
; cluster similar items
temps: [22 22 23 25 25 25 24 24]
clusters: cluster temps 'temp -> temp
; [[22 22] [23] [25 25 25] [24 24]]
; chunk using predicate
data: 1..6
chunks: chunk data => [& < 3]
[1 2] [3 4 5 6]
; finding matches with collect
numbers: [1 2 3 2 1 4 5 4]
duplicates: collect.after numbers 'x ->
not? contains? first.n:3 numbers x
; 4 5 4
Pipe-based Transformations
; Sample data: list of orders
orders: @[
#[id: 1 items: ["book" "pen"] total: 25.50 status: "pending"]
#[id: 2 items: ["laptop"] total: 999.99 status: "completed"]
#[id: 3 items: ["phone" "case" "charger"] total: 699.00 status: "pending"]
#[id: 4 items: ["tablet"] total: 299.99 status: "cancelled"]
]
; Process orders using pipes for better readability
result: orders
| select 'order -> order\status = "pending" ; get pending orders
| map 'order -> #[ ; transform structure
orderId: order\id
itemCount: size order\items
cost: order\total
]
| arrange 'order -> order\cost ; sort by cost
| map 'order -> ~{
Order #|order\orderId|: |order\itemCount|
items @ $|order\cost|
}
print.lines result
; Order #1: 2
; items @ $25.5
; Order #3: 3
; items @ $699.0
Tip
Using pipes (|) can make complex data transformations more readable by breaking them into clear, sequential steps.