Imperative Code as Streams

In imperative languages, you usually get a new random number by calling a function (such as C’s rand(3)) when you need a new one. You can do this in a functional language like Haskell too, but then you’re forced into an imperative style, which isn’t very functional. (An imperative style would be required because generating a new random number depends on the current state of the random number generator.) You can keep a functional programming style by having a random number generator produce a (lazy) list of numbers, rather than a single number: any code which wants a random numbers simply pulls the next one out of the list. I posted some example code to the haskell-cafe mailing list recently to demonstrate this, in answer to a Haskell newcomer’s post. Lazy lists are often also called streams.

Normally, monads are used to encapsulate state changes in Haskell in a purely functional manner, but you can use streams too: any state changes which occur can be represented with new list elements. It’s no coincidence that streams are monads: they’re powerful enough to sequence non-deterministic operations. The Haskell Ports Library gives you even more convenience when working with streams by modelling time as a list, and the awesome iHaskell and Fudgets libraries for Haskell manage to model an entire GUI in a purely functional manner. Just to show that this is also has a practical benefit, the Fudgets code examples show how succinct writing GUI code can be. The Fudgets thesis is a great introduction and explanation to how it all works.

Closely related is the newer concept of arrows, which provide a formal framework to reason about stream-based (and also various other non-stream-based) computations. Anyone up for writing a Haskell library to interface to the gstreamer media framework as an arrow?

blog comments powered by Disqus