Malcolm Wallace wrote:
Simon Marlow <[EMAIL PROTECTED]> 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.

Glasgow-haskell-users mailing list

Reply via email to