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 avalueproperty for the iterated element, and adoneproperty indicating whether the iterator is exhausted. (Whendoneis true,valueis 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 exceptionStopIterationto 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$Foldablemight 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$