Iterators
Pyro's for
loop uses a simple iterator protocol for iterating over sequences of values, e.g.
for item in [123, 456, 789] { echo item; }
An object is iterable if it has an :$iter()
method.
This method should return an iterator — i.e. an object with a :$next()
method that returns either the next item from a sequence or an err
if the sequence has been exhausted.
Most of Pyro's builtin container types — e.g. vec
, tup
, map
, etc. — are iterable.
You can find a tutorial on implementing the iterator protocol for custom types here.
Example
We can illustrate the iterator protocol by creating a custom Range
object to iterate over a range of integers:
class Range { var next = 0; var stop; def $init(stop) { self.stop = stop; } def $iter() { return self; } def $next() { if self.next < self.stop { self.next += 1; return self.next - 1; } return $err(); } }
Note that in this case the :$iter()
method simply returns self
— i.e. a Range
instance is its own iterator.
We can try out our new Range
type like this:
for i in Range(5) { echo i; }
This gives us the following output:
0 1 2 3 4
(In practice, you don't need to implement this functionality yourself — Pyro already has a builtin $range()
function that returns an iterator over a range of integers.)
Iterator Wrappers
Pyro has a builtin function called $iter()
that can wrap any iterator in a special iter
type that automatically adds support for a set of chainable, lazily-evaluated utility methods.
We can try it out on our custom Range
type.
First, let's define some callback functions:
def is_even(n) { return n % 2 == 0; } def square(n) { return n * n; }
Now we can apply them using :filter()
and :map()
:
for i in $iter(Range(10)):filter(is_even):map(square) { echo i; }
This gives us the following output:
0 4 16 36 64
All the iterators returned by Pyro's builtin types and functions come pre-wrapped in iter
wrappers so we could get an identical result using the builtin $range()
function without needing to call $iter()
:
for i in $range(10):filter(is_even):map(square) { echo i; }
You can learn more about iterator wrappers here.