Many high-level languages have some kind of protocol or interface for iterators, allowing user-defined types to be used in "for-each" loops. A few examples from popular languages:
- In Java, a class which implements the
Iterator<E>
interface must provide ahasNext()
method to indicate whether the iteration should continue, and anext()
method to return the next iterated element. Additionally, there is an optionalremove()
method to remove the element previously returned bynext()
from the underlying collection. - In Javascript, an object implements the iterator protocol by providing a
next()
method returning an object with avalue
property for the iterated element, and adone
property indicating whether the iterator is exhausted. (Whendone
is true,value
is not required.) - In Python, a class can be iterable in two ways:
- It can have a
__len__
method and a__getitem__
method to represent an iterable sequence, where each element can be accessed by index; - It can have an
__iter__
method returning an iterator object, which provides a__next__
method. When this method is called, it either returns the next iterated element, or it raises the special exceptionStopIteration
to indicate that the iterator is exhausted.
- It can have a
These protocols differ in the methods that the object must provide, and the expected behaviour of those methods. What are the advantages and disadvantages of these designs, or of other iteration protocols from other languages?
{value: 23, done: true}
to indicate a return value from a generator. $\endgroup$Foldable
might be another approach worth noting--not that it actually supports imperative for-loops, but the general idea is certainly applicable: rather than provide hooks for a for-loop to iterate with, the type provides the entire loop construct itself. $\endgroup$IEnumerator<T>
hasbool MoveNext()
andT Current
, as well as an optionalvoid Reset()
to support restarting mid-iteration. $\endgroup$