[GHC] #5129: "evaluate" optimized away

GHC ghc-devs at haskell.org
Fri Jan 9 10:34:01 UTC 2015


#5129: "evaluate" optimized away
-------------------------------------+-------------------------------------
        Reporter:  dons              |                   Owner:  simonmar
            Type:  bug               |                  Status:  closed
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.0.3
      Resolution:  fixed             |                Keywords:  seq,
Operating System:  Unknown/Multiple  |  evaluate
 Type of failure:  Incorrect result  |            Architecture:
  at runtime                         |  Unknown/Multiple
      Blocked By:                    |               Test Case:
 Related Tickets:                    |                Blocking:
                                     |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by simonpj):

 A later note, in the light of [https://www.haskell.org/pipermail/ghc-
 devs/2015-January/007900.html this email thread].
 Looking at the Haddock documentation for `evaluate`, Roman said: we seem
 to have three possible
 implementations for `evaluate`:
 {{{
 1) evaluate x  = return $! x
 2) evaluate x  = (return $! x) >>= return
 3) evaluate x = \s -> seq# x s
 }}}
 Now (1) is too strict: `(evaluate (error "urk") True)` should yield
 `True`.

 And, contrary to my claim in the email thread, (2) suffers from comment:2
 above: inlining can mean that the argument to `evaluate` never gets
 evaluated.

 Consider, under (2)
 {{{
 evaluate = \x -> (return $! x) >>= return
          = \x. \s.  case return $! x s of (s1, r) -> return r s1
          = \x s. x `seq` case (s,x) of (s1, r) -> return r s1
          = \x s. x `seq` (s,x)
          = \x s. case x of _ -> (s,x)
 }}}
 Now consider the call in comment:2:
 {{{
 evalutate poss_err >> assertFailure "foo"`

 = (inline >>)
   \s -> case evaluate poss_err of (s1, _) -> assertFailure "foo" s1

 = (inline evaluate)
   \s -> case (case x of _ -> (s,x)) of (s1, _) -> assertFailure "foo" s1

 = (case of case)
   case x of _ -> assertFailure "foo" s1
 }}}
 and now, as explained in comment:2, since `assertFailure` diverges, GHC
 feel free to discard the case on `x`.

 Using a primop `seq# :: a -> State# -> (State#, a)` means that the I/O
 options that follows,
 which consumes the state that comes out of the `seq#` simply can't start
 until the `seq#` has
 executed.  And that is what we want for `evaluate`.

 So only (3) will do.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/5129#comment:17>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list