The documentation of seq
function says the following:
A note on evaluation order: the expression
seq a b
does not guarantee that
I only see such a difference with optimizations turned off.
With ghc -O
both pseq
and seq
perform the same.
The relaxed semantics of seq
allow transformations resulting in slower code indeed. I can't think of a situation where that actually happens. We just assume GHC does the right thing. Unfortunately, we don't have a way to express that behavior in terms of a high-level semantics for Haskell.
Why pseq is slower?
pseq x y = x `seq` lazy y
pseq
is thus implemented using seq
. The observed overhead is due to the extra indirection of calling pseq
.
Even if these ultimately get optimized away, it may not necessarily be a good idea to use pseq
instead of seq
. While the stricter ordering semantics seem to imply the intended effect (that go
does not accumulate a thunk), it may disable some further optimizations: perhaps evaluating x
and evaluating y
can be decomposed into low-level operations, some of which we wouldn't mind to cross the pseq
boundary.
Does there exist some example where seq a b has different results depending on evaluation order (same code but different compiler flags/different compilers/etc.)?
This can throw either "a"
or "b"
.
seq (error "a") (error "b")
I guess there is a rationale explained in the paper about exceptions in Haskell, A Semantics for imprecise exceptions.