<p dir="ltr">Well, the value of par x y is identical to that of y, so any expression which you could use to semantically distinguish pseq from seq using par could be rewritten into one which did so without involving par.</p>
<p dir="ltr">If the way in which we're telling programs apart involves performance characteristics then it may already be possible to distinguish seq from pseq. It somewhat comes down to whether the implementation of the language is clever enough to notice when compiling seq x y any cases where it might be better to finish evaluating y first and simply evaluate x before making the result of that first evaluation available. GHC does do this rearranging, so probably someone can come up with a good example there.</p>
<div class="gmail_quote">On Apr 29, 2016 5:38 PM, "José Manuel Calderón Trilla" <jmct@jmct.cc> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello Takenobu,<br>
<br>
Great question, this is actually a pretty interesting issue! It isn't<br>
out of scope at all.<br>
<br>
The first thing to think about is the following thought experiment:<br>
<br>
Without the presence of side-effects, how can you tell the difference<br>
between a `seq` that conforms to the Haskell report and one that<br>
evaluates it's first argument before its second?<br>
<br>
If your answer involves `unsafePerformIO` then you're cheating ;)<br>
<br>
Even if your first argument to `seq` is an IO action it won't get<br>
executed because `seq` only evaluates to WHNF. It might be possible to<br>
construct a program that allows you to observe the difference, but in<br>
the general case I don't see how you could. I'd be very interested to<br>
be shown otherwise though!<br>
<br>
Now in a parallel program things change. When we use `pseq` it's<br>
because we don't want two threads to collide when trying to evaluate<br>
the same expression. Let's look at an example:<br>
<br>
x `par` y `seq` x + y<br>
<br>
As you noted, the semantics of `seq` doesn't actually guarantee that<br>
`y` will be evaluated before `x + y`. But this only matters because<br>
we've used `par` and introduced threads (via an effect!) and therefore<br>
the possibility of collision. We can avoid this by using `pseq`<br>
instead.<br>
<br>
So, both `seq` and `pseq` both allow the programmer to express<br>
*operational* concerns, `seq` is used mostly to eliminate/manage space<br>
leaks, and `pseq` is used to specify order of evaluation. Those<br>
concerns sometimes overlap, but they are different!<br>
<br>
It could be argued (and I would agree) that `seq` is a bad name; a<br>
better name might have been something like `synch` [1]. That being<br>
said, unless we add parallelism to the standard (and even then) I am<br>
not sure it would be wise to change the operational behavior of `seq`.<br>
It's current behavior is well established, and if you're writing<br>
sequential Haskell code where order of evaluation matters, it's<br>
probably better to reach for a different tool (IMO). However, if<br>
parallelism is introduced then I'd fight for `pseq` to be part of that<br>
(as you suggest).<br>
<br>
I hope that sheds some light on the issue.<br>
<br>
Cheers,<br>
<br>
Jose<br>
<br>
[1]: John Hughes introduced a `synch` combinator in his thesis, but it<br>
had very different semantics, so maybe that's a reason it was avoided?<br>
Someone with more knowledge of the history can probably shed more<br>
light on this.<br>
<br>
<br>
On Thu, Apr 28, 2016 at 6:56 PM, Takenobu Tani <<a href="mailto:takenobu.hs@gmail.com">takenobu.hs@gmail.com</a>> wrote:<br>
> Dear Community,<br>
><br>
> Apologies if I'm missing context.<br>
><br>
> Does Haskell 2020 specify evaluation order control by `pseq`?<br>
><br>
> We use `pseq` to guarantee the evaluation order between two expressions.<br>
> But Haskell 2010 did not specify how to control the evaluation order between<br>
> two expressions.<br>
> (only specified `seq` in Haskell 2010 section 6.2 [1]. but `seq` don't<br>
> guarantee the order. [2])<br>
><br>
> I think it's better to explicitly specify `pseq` as standard way.<br>
><br>
> Already discussed? or out of scope?<br>
><br>
> [1]:<br>
> <a href="https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1260006.2" rel="noreferrer" target="_blank">https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1260006.2</a><br>
> [2]:<br>
> <a href="https://www.schoolofhaskell.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens" rel="noreferrer" target="_blank">https://www.schoolofhaskell.com/user/snoyberg/general-haskell/advanced/evaluation-order-and-state-tokens</a><br>
><br>
> Regards,<br>
> Takenobu<br>
><br>
><br>
> _______________________________________________<br>
> Haskell-prime mailing list<br>
> <a href="mailto:Haskell-prime@haskell.org">Haskell-prime@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime</a><br>
><br>
_______________________________________________<br>
Haskell-prime mailing list<br>
<a href="mailto:Haskell-prime@haskell.org">Haskell-prime@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime</a><br>
</blockquote></div>