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:
:get returns the next element or pair of the collection, if any
:more? returns true if there are more elements remaining
:done? returns true if there are not more elements remaining (for convenience)
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.