seq vs. pseq
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
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.
More information about the Glasgow-haskell-users