
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
#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]: 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