Streams and Iterators - Spicery/Nutmeg GitHub Wiki
Streams and iterators are two-sides of the same coin. Both are ways of generating a linear sequence of values. Streams are the declarative version of iterators:
### Iterators are stateful and advance to the next item automatically.
iterator.next() -> T else None
### A stream always returns the same head element. You need to access the tail to get the next elements.
stream.head() -> T else None
stream.tail() -> Stream<T> else None
stream.isEmpty() -> bool
stream.dest() -> (T, Stream<T>) else None
### Streams and iterators can be easily interconverted. Streams are therefore iterable and iterators are streamable.
stream.asIterator() -> Iterator<T>
iterator.asStream() -> Stream<T>
interface Iterator<T>:
^next() -> T else None
end
interface Stream<T>:
^head() -> T else None
^tail() -> Stream<T> else None
def ^isEmpty():
try ^head():
case None: True
case _: False
end
end
def ^dest() -> _ else None:
^head()?
^tail()?
end
end
New streams can be easily be generated by mapping over streamables, such as a Range.
stream.Map(f)
Both streams and iterators can be expanded, yielding all their values, with the expand
function.
>>> println( expand(0..<5) )
01234