[Haskell-cafe] Why?

Paul Johnson 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...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20091211/43faeedb/attachment.html

More information about the Haskell-Cafe mailing list