[GHC] #13330: forkIO has inconsistent behavior under optimization

GHC ghc-devs at haskell.org
Fri Feb 24 23:03:45 UTC 2017


#13330: forkIO has inconsistent behavior under optimization
-------------------------------------+-------------------------------------
        Reporter:  dfeuer            |                Owner:  dfeuer
            Type:  bug               |               Status:  patch
        Priority:  normal            |            Milestone:  8.2.1
       Component:  Core Libraries    |              Version:  8.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  Other             |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):  Phab:D3189
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by dfeuer):

 Replying to [comment:4 simonpj]:
 > Strange. The definition of `catch` is just
 > {{{
 > catch act = catchException (lazy act)
 > }}}
 > for reasons extensively documented in #11555.  So `catchException` has
 different, less desirable, and undocumented behaviour.
 >
 > Should move the `lazy` into `catchException`?  So then `catch =
 catchException`.  Do we actually want the distinction?
 >
 > Incidentally, the use of 'lazy' in `catch` is entirely un-documented.
 No `Note` no nothing.  While fixing this ticket it would be good to fix
 that too.  At every least a reference to #11555!

 Yes, I can document the `lazy` in `catch`. The distinction probably
 ''does'' make sense, although it was documented quite incorrectly. The
 situation here is a bit tricky: we are trying to deal with the fact that
 `catch#` evaluates its argument ''eagerly'', but is nevertheless ''non-
 strict'' in that argument. The current approach is to lie a little and
 tell the demand analyzer that `catch#` is strict in its argument.
 `catchException` inherits this lie.

 To avoid getting caught in a lie, and to avoid fragile case-specific
 reasoning, the invariant we must maintain is that `catchException` is
 never called with an undefined argument. When this invariant holds, the
 analysis should end up being pretty much correct:

 1. It's safe to evaluate the argument and/or its dependencies early,
 because it will not fail.

 2. After the `catchException` runs, its argument will be in WHNF.

 An alternative approach that smells more honest to me might be to reveal
 the fact that `catch#` is actually lazy in its argument, remove the `lazy`
 call from `catch`, and make `catchException` actually force its argument.
 I don't know if that would have any negative performance or other
 consequences.

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


More information about the ghc-tickets mailing list