What is the connection between laziness and purity?

You’re right, from a modern POV this doesn’t really make sense. What is true is that lazy-by-default would make reasoning about side-effectful code a nightmare, so lazyness does require purity – but not the other way around.

What does require lazyness though is the way Haskell in versions 1.0–1.2, following its predecessor Miranda, emulated IO without monads. Short of any explicit notion of side-effect sequencing, the type of executable programs was

main :: [Response] -> [Request]

which would, for a simple interactive program, work something like this: main would at first just ignore its input list. So thanks to lazyness, the values in that list wouldn’t actually need to exist, at that point. In the meantime it would produce a first Request value, e.g. a terminal prompt for the user to type something. What was typed would then come back as a Response value, which only now actually needed to be evaluated, giving rise to a new Request, etc. etc..

https://www.haskell.org/definition/haskell-report-1.0.ps.gz

In version 1.3 they then switched to the monadic-IO interface that we all know and love today, and at that point lazyness wasn’t really necessary anymore. But before that, common wisdom was that the only way to interact with the real world without lazyness was to allow side-effectful functions, thus the statement that without lazyness, Haskell would just have gone down the same path as Lisp and ML before it.

Leave a Comment