[haskell-cafe] Monad and kinds

Derek Elkins derek.a.elkins at gmail.com
Fri Sep 5 22:23:14 EDT 2008

On Thu, 2008-09-04 at 08:19 -0700, Tim Chevalier wrote:
> On 9/3/08, wren ng thornton <wren at freegeek.org> wrote:
> >  If you want the datatype to be strict in state and rec, then you should add
> > strictness annotations to those fields directly:
> >
> >     data Query state rec = Query !state !rec
> The novice programmer scatters strictness annotations to and fro like
> dust in the wind. The average programmer understands that annotating a
> field's strictness injudiciously is like discarding the finger
> pointing at the moon when you might still need it to scratch yourself.
> The master programmer does not add strictness annotations, for she has
> not yet run the profiler.

This attitude is wrong.  Many potentially significant performance
problems can easily be spotted and solved during construction without
affecting the readability of the code, problems that would be much
harder to diagnose at the end running a profiler.  This is especially
crucial for library code.  The users of the library may be the ones that
find the easily resolved space leak your profiling didn't reveal and now
they can't do anything about it until a new version is released e.g.
Data.Map.insertWith. A performance problem that renders your code
unusable is a bug and catching it early or not making it in the first
place is much better than catching it late.

A (highly related) analogy would be telling Scheme programmers (or
Haskell programmers for that matter) not to use to tail recursive code
until a profiler tells them to and transforming to a tail recursive
style is much more intrusive than adding a strictness annotation.

Highly competent Haskell programmers add strictness annotations
relatively systematically.  The details of mixing eager and lazy code is
one of the significant contributions to the pragmatics of programming
lazy functional languages have made.  At another extreme, things like
Chris Okasaki's data structures rely on a specific balance of eagerness
and laziness.

Also, it is easier (as in not impossible) to turn a strict in the
elements data structure into a lazy one than the other way around.

Eager by default or lazy by default are both have (actually dual)
pitfalls that are best solved by a laziness or strictness annotation
respectively.  There is no need to walk into those pitfalls with your
eyes wide open.

More information about the Haskell-Cafe mailing list