
#14521: Infinite loop at runtime -------------------------------------+------------------------------------- Reporter: OlivierSohn | Owner: (none) Type: bug | Status: closed Priority: high | Milestone: 8.2.3 Component: Compiler | Version: 8.2.2 Resolution: invalid | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): I took a quick look. To me it looks as if it should definitely loop. Look at the code {{{ animatedNumber n = animate' (mkAnimator animateNumberPure animatedNumber n) mkAnimator pure_ io_ params = Animator (applyAnimation (pure_ params)) (io_ params) animate' (Animator pure_ io_) = animate pure_ io_ }}} If we just inline `mkAnimator` we see: {{{ animatedNumber n = animate' (Animator blah (animatedNumber n)) }}} Now * `Aminator` is declared to be strict in its second argument * `animate'` is certainly strict So of course `animatedNumber n` will just return bottom. The mystery is not why it diverges -- it should! -- but rather why it sometimes fails to diverge. The answer is that GHC allows itself a bit of leeway in making a divergent program into one that converges, in the interests of improving runtimes generally by allowing more optimisations. You can switch off this behaviour by using `-fpedantic-bottoms`, and then sure enough it always diverges. In this case the relevant optimisation is eta-expansion. If you do manual eta-expansion on `animate'`, then it converges, always: {{{ animate' :: Animator a -> Tree -> Animation -> IO (Maybe Animation) animate' (Animator pure_ io_) t a = animate pure_ io_ t a }}} -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14521#comment:21 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler