Always guaranteed evaluation order of `seq` (with strange behavior of `pseq` in addition)

前端 未结 3 940
既然无缘
既然无缘 2021-02-12 20:44

The documentation of seq function says the following:

A note on evaluation order: the expression seq a b does not guarantee that

3条回答
  •  梦如初夏
    2021-02-12 21:21

    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.

提交回复
热议问题