[Haskell-cafe] strict version of Haskell - does it exist?

Jan-Willem Maessen jmaessen at alum.mit.edu
Mon Jan 30 15:07:26 CET 2012

On Mon, Jan 30, 2012 at 6:24 AM, Malcolm Wallace <malcolm.wallace at me.com>wrote:

> On 29 Jan 2012, at 22:25, Ertugrul Söylemez wrote:
> > A strict-by-default Haskell comes with the
> > implication that you can throw away most of the libraries, including the
> > base library.  So yes, a strict-by-default Haskell is very well
> > possible, but the question is whether you actually want that.  I
> > wouldn't, because a lot of my code relies on the standard semantics.
> At work, we have a strict version of Haskell, and indeed we do not use the
> standard libraries, but have built up our own versions of the ones we use.
>  However, our compiler is smart enough to transform and optimise the source
> code *as if* it were non-strict: it is only at runtime that things are
> evaluated strictly.  This means that, in general, you can rely on the
> standard semantics to a surprisingly large extent.

I wanted to emphasize Malcolm's point here.  Optimizing using the original
Haskell semantics turned out to be pretty important back when I was working
on Eager Haskell.  For example, a lot of Haskell functions are written in
the following style:

f a b c
  | guard1 d = g h i
  | guard2 e = h
  | guard3 f = i
  | otherwise = j
  where d = ...expensive...
        e = ...expensive...
        f = ...expensive...
        g = ...expensive...
        h = ...expensive...
        i = ...expensive...
        j = ... expensive...

An an ordinary procedural language, where function calls in g, h, i, and j
might have side effects, we can't sink bindings down to the point of use.
 Even in the absence of side effects, we have to account for the fact that
some of these computations are used in some -- but not all -- right-hand
sides, and that often we need to do some inlining to discover that a value
isn't going to be used.  It turns out Haskell code relies on this sort of
thing all over the place, and simply coding around it leads to
deeply-nested let bindings that walk off the right-hand edge of the screen.

It's not difficult to rewrite most of the prelude functions in this style,
but it's no longer pretty, and it's recognizably not idiomatic Haskell.

However, bulk operations do transform the entire data structure, not merely
> the fragments that are needed for the onward computation, so it can often
> be a net performance loss.  The standard lazy computational paradigm of
> generate-and-test is therefore hideously expensive, on occasion.

This was a huge issue in Eager Haskell.  By far our worst performance was
on stream-like programs that generated infinite lists of results, and then
sliced away the useless tail.  With completely strict evaluation, this of
course doesn't work at all, but it can be tricky to bound the required
sizes of inputs even if you know how much of the output you want (imagine a
call to takeWhile or filter on an infinite list).

-Jan-Willem Maessen

> Regards,
>    Malcolm
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20120130/1096d757/attachment.htm>

More information about the Haskell-Cafe mailing list