paul at cogito.org.uk
Fri Dec 11 14:27:31 EST 2009
On 10/12/09 12:07, Magnus Therning wrote:
> As I understand it it all started with laziness. I don't know if
> laziness is impossible without purity, but talks and papers tend to
> say something like "laziness has kept Haskell pure".
This is true, but laziness has its own advantages. Suppose I have two
modules, Foo and Bar. Foo generates a data structure which is then
consumed by Bar (possibly with some other component calling both of
them). In a strict language I have to choose between one of these three
1. Foo generates the structure all at once, and some kind of
reference is then passed to Bar. This is nice, simple and
modular, but it only works for small structures. There can also
be a problem if the structure is slow to generate but is only
consumed a bit at a time (e.g. by the user interface) because Bar
can only start work once Foo has finished the whole thing. You
may also find the Foo is doing lots of unnecessary work building
bits of the structure that Bar uses only rarely.
2. Foo and Bar are built together in a single module with their
functionality interleaved. This means that Foo can build a bit of
the structure, have Bar process it, and so on. However it also
destroys any modularity the system might have had. If Bar is part
of the user interface, for instance, it means that core
functionality gets mixed up.
3. Implement some kind of generator object. This takes a lot of code
and makes the logic of Foo and Bar harder to follow. For instance
the version of Foo from option 1 might have had a loop of the form
"foreach i in xs". Now "i" has to be turned into some kind of
member variable with logic to move to the next instance. Of
course what you are really doing is creating an ad-hoc hand-coded
version of lazy evaluation.
Different applications are going to require different choices. Worse
yet, the right answer can change. For instance you may start with
option 1, then discover that the program runs too slowly. Or marketing
decide that the maximum size of the data structure has to be increased.
So at that point you have to rewrite a big chunk of code. Or else you
go with option 2 or 3 because the designer thought it was necessary for
efficiency when in fact option 1 would have done nicely.
Of course with lazy evaluation you get option 3 all the time
automatically. So its just not a problem. This makes the design much
simpler because things that previously had to be decided by a human are
now decided by the compiler.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe