seq vs. pseq

Simon Marlow simonmarhaskell at gmail.com
Mon Nov 6 07:53:55 EST 2006


Malcolm Wallace wrote:
> Simon Marlow <simonmarhaskell at gmail.com> wrote:
> 
> 
>>The difference is subtle.  The semantics of seq and pseq are
>>identical; however,  GHC can see that seq is strict in both its
>>arguments and hence could choose to  evaluate them in either order,
>>whereas pseq is only strict in its first argument  as far as the
>>strictness analyser is concerned.  The point is that pseq is  useful
>>for controlling evaluation order, which is what you want for adding 
>>parallelism to a program.  seq, on the other hand, is not useful for
>>controlling  evaluation order.
> 
> This is a rather weird thing, and I would consider it a bug in the
> Haskell Report, rather than a bug in ghc.  (It bites hard when you are
> trying to implement something like HPC.)
> 
> The very name 'seq' surely suggests that you are controlling the
> evaluation order.  "Please evaluate this thing on the left first".  But
> that is _not_ what the Haskell Report says!  Ghc takes the Report
> literally, and so the thing on the right is just as likely to be
> evaluated before the thing on the left!

The report is in general very careful to say absolutely *nothing* about 
evaluation order, leaving the implementation free to choose, either at compile 
time or possibly even runtime.  This is an important principle, and something I 
feel quite strongly should be kept at the front of our minds for Haskell Prime. 
  If it isn't already mentioned explicitly in the Haskell 98 report, I think it 
should be.

Incedentally, this is also one reason I think lazy I/O is a wart (despite its 
obvious usefulness): because it necessarily requires talking about evaluation order.

However, having said all that, arguably an exception should be made in this 
case.  The main use of seq (and strictness annotations) is to control 
operational behaviour, rather than to change the semantics of the program - for 
example, it is most often used to prevent space leaks by "evaluating something 
earlier than it would otherwise be" (inverted commas because this isn't 
currently what seq actually does, as pointed out above).

Indeed, if GHC was in the habit of causing the second argument of seq to be 
evaluated before the first, then a lot of people would probably be surprised. 
eg. imagine what happens to foldl':

   foldl' f a []     = a
   foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs

It wouldn't do what you want at all.

So I'm agreeing with Malcolm, except that I believe that the evaluation-order 
property of seq should be a strong hint, not a requirement - otherwise we fall 
into the trap of mandating evaluation order.

Cheers,
	Simon


More information about the Glasgow-haskell-users mailing list