Lazy Iteration
An array’s .map() builds a new array straight away. An iterator’s .map() does nothing yet: it
returns a new iterator that will map values when something asks for them. That difference —
eager versus lazy — is what lets iterators work on sequences that are large, or that never
end.
A pipeline that runs when you pull
Section titled “A pipeline that runs when you pull”An iterator is pull-based. Methods like filter, map, take and skip each wrap the iterator in
front of them and return immediately. Only a consuming method — collect, count, fold, find,
next and the rest — pulls values through the chain, one at a time:
let result = #[1, 2, 3, 4, 5, 6, 7, 8] .iter() .filter(fn(x) { return x % 2 == 0; }) // nothing runs yet .map(fn(x) { return x * 10; }) // nothing runs yet .collect(); // now every stage runs, value by valueprint(result); // [20, 40, 60, 80]No intermediate array is built between filter and map. Each value goes through every stage
before the next one starts, and a consuming method that has its answer stops pulling: find stops
at the first match, any at the first true.
Single use
Section titled “Single use”An iterator is a position in a sequence, not the sequence itself. Once a value has been pulled, it
is gone; an exhausted iterator returns NUL from next() and yields nothing more. Calling
collect() twice on one iterator gives you the elements, then an empty array. To go over the data
again, ask the source for a new iterator with .iter(). The source is unchanged, because iterating
never modifies it.
Why a pattern iterator never ends
Section titled “Why a pattern iterator never ends”A pattern is a query over an endless stream of cycles,
so an iterator over its events never runs out. Laziness is what makes that workable: .take(8)
caps the sequence, and everything after it sees exactly eight events.
let notes = [C4 E4 G4].iter() .take(6) .map(fn(e) { return e.note(); }) .collect();print(notes); // [60, 64, 67, 60, 64, 67]The flip side is that a consuming method on an uncapped pattern iterator — collect, count,
last, fold — waits for an end that never comes. Put .take(n) first, every time.
Next Steps
Section titled “Next Steps”- Collections & Iterators — iterator sources and method groups
- Iterator methods — every method, with its signature