[GHC] #15143: Passing an IO value through several functions results in program hanging.
GHC
ghc-devs at haskell.org
Thu May 17 22:17:23 UTC 2018
#15143: Passing an IO value through several functions results in program hanging.
-------------------------------------+-------------------------------------
Reporter: Burtannia | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.6.1
Component: Compiler | Version: 8.4.2
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
Type of failure: Runtime | Unknown/Multiple
performance bug | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by simonpj):
Why do you think this is a bug?
You are compputing
{{{
incTime (incTime ( ... (incTime testObs) ... ))
}}}
where
{{{
incTime :: IO Obs -> IO Obs
incTime o = do obs <- o
case obs of
ObsTime t -> return $ ObsTime (t+1)
_ -> o
}}}
Each call of `incTime` invokes its argument `o` twice. Since `o` is
passed in as an argument, GHC ''must'' call it twice in case it has side
effects. The alternative code
{{{
incTime' o = do obs <- o
case obs of
ObsTime t -> return $ ObsTime (t+1)
_ -> return obs
}}}
is not semantically equivalent. Imagine called
{{{
incTime (do { updRef r (+ 1); return ObsTemp })
}}}
then I expect the reference `r` to be incremented twice. But `incTime'`
will only increment it once.
So each call to `incTime o` calls `o` twice. But in the call `incTime
(incTime o)`, we call `incTime o` twice; and each call calls `o` twice.
Result: four calls to `o`. If the nest is 3 deep we get eigth calls and
so on.
In short, this program has exponential runtime ''by design'', and GHC
faithfully does what you ask.
In short, it looks fine to me. Do you agree?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15143#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list