Skip to content

Sequence, iterator, and coordinate protocols

jckarter edited this page Nov 18, 2010 · 10 revisions

Sequences and iterators

A sequence type is any type for which the iterator function is defined. The iterator object is used to access the elements of the sequence one at a time. The type of the iterator object must support the hasNext? and next operations. hasNext? returns a Bool value indicating whether there are elements left to be accessed, and next accesses the next available value. The behavior of next is undefined if hasNext? returns false. Here is an example sequence object Iota that produces a sequence of integers via an IotaIterator:

  record Iota (n: Int);
  record IotaIterator (i: Int, n: Int);

  overload iterator(iota: Iota) = IotaIterator(0, itoa.n);
  overload hasNext?(ii: IotaIterator) = ii.i < ii.n;
  overload next(ii: IotaIterator) {
      var i = ii.i;
      inc(ii.i);
      return i;
  }

We can now use the Iota object in a for loop:

  for (n in Iota(5))
      println(n, " senses working overtime");

This sequence type can also be used with mapped, filtered, and sequence converting constructors such as Vector(Iota(5)).

next may return multiple values, and for loops support this syntactically. An example is zipped:

  for (x, y in zipped(["apple", "lemon", "chocolate"], ["pie", "meringue", "cake"]))
      println(x, " ", y);

As indicated in Syntax desugaring, a for (elem in seq) loop expands to a while loop using iterator, hasNext? and next calls:

    var iter = iterator(seq);
    while (hasNext?(iter)) {
        ref elem = next(iter);
        <for loop body>;
    }

The Sequence? type predicate returns true for any type T for which iterator(x: T) is defined. The Iterator? predicate returns true for any type T for which hasNext?(x: T) and next(x: T) are defined. The following functions are available for Sequence? types:

  • SequenceElementType(T) returns the type of elements of T, that is, the return type of next when called for iterators of T.

and for Iterator? types:

  • IteratorTargetType(T) returns the type of elements produced through T.

Reversible sequences

A sequence may also implement reverseIterator to support the reversed function.

  record IotaReverseIterator (i: Int);
  overload reverseIterator(iota: Iota) = IotaReverseIterator(iota.n);
  overload hasNext?(iri: IotaReverseIterator) = iri.i > 0;
  overload next(iri: IotaReverseIterator) {
      dec(iri.i);
      return iri.i;
  }
  for (n in reversed(Iota(5))
      println(n, " bottles of beer");

Clone this wiki locally