7.2 Stateful Iterators

FSet’s stateful iterators are objects implemented as closures; you invoke operations on them with funcall, passing a keyword symbol to specify the operation. They are stateful in that each :get call advances the iterator, so the next call will return the next element; in this, they behave like streams. To obtain a stateful iterator, call iterator on the collection. The operations on them are:

Specifically, on a set iterator or a non-pair bag iterator, :get returns two values. If the iterator is not exhausted (there are more elements remaining), it returns the next element and a true second value; if it is exhausted, it returns nil and false. On a map iterator, a pair bag iterator, or a 2-relation iterator, it returns three values: if not exhausted, the domain element, the range element or multiplicity, and true; if exhausted, two nils and false.

So there are actually three ways to detect exhaustion: :more? or :done?, which return booleans with opposite senses, or just call :get until the second or third value is false. Use whichever is most convenient.

FSet provides stateful iterators on these classes: set, map, bag, seq, replay-set, replay-map, and 2-relation. For convenience, it also provides iterator methods on these CL builtin types: list, vector, string, and sequence.

The stateful iterators are not thread-safe.