A stream is a sequence of values, like a mathematical series could be. This series of values is provided by function; at each invocation the function returns a pair containing:
- a fresh new value belonging the stream
- a function that, once called, will return the next pair value+function of the stream
The logic that determines the next value of the stream is encapsulated in the abovementioned function. Because the function invocation provides one value and awaits our active request before serving another one, streams are in condition to represent inside our programs even infinite series of values while assuring us that there will be no overflow.
Streams are magnificently presented in this post, using Racket as language for the examples.
Using streams to organize unorganized computations
This is a placeholder for a future text about the usage of streams in case a chain of computations is not producing a well-organized c.q. predictable result. The text will present a couple of examples of real-world problems I have solved this way.
A typical application is when we are stepwise reducing a tree but aren’t able to predict when/how the process will end.
By capturing the computation in a stream we are able to serve the chain of results in a consistent manner, for example as list elements that can be processed by higher order operators like monads and folds. We can provide the stream with the logic for telling when the series is over and signal it to the invoking algorithm.