[GHC] #13080: Memory leak caused by nested monadic loops
GHC
ghc-devs at haskell.org
Fri Jan 13 14:32:44 UTC 2017
#13080: Memory leak caused by nested monadic loops
-------------------------------------+-------------------------------------
Reporter: Feuerbach | Owner:
Type: bug | Status: new
Priority: normal | Milestone: 8.2.1
Component: Compiler | Version: 8.0.1
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 nomeata):
> do we intend for bar to be recomputed on each call to foo, or shared
globally?
The answer to this question depends heavily on what it means for “foo” to
be called! Consider this:
{{{#!hs
foo :: Int -> IO ()
foo x = …
where bar = expensive x
}}}
If we now run `mapM (foo 1) [1.1000]`, then, in one sense, the function
`foo` is called once (when passed `x`). This returns a value of type `IO
()`, which is then executed 1000 times. This is the sense that the
compiler understands, and without further hacks, `bar` would be evaluated
only once here. Some users know and expect this.
But there is another sense where one thinks of a call to `foo` as the
execution of the `IO` action produced by `foo 1`. This is probably how
most users in most cases think about functions returning an `IO`
something. . With the current implementation of `IO ()`, this is when the
state token is passed to the function wrapped in `IO ()`.
The state hack is about eta-expanding `foo` so that these notions
coincide. Unfortunately, and as far as I can tell, there is no way of
writing `foo` to get this result directly (without breaking the `IO`
abstraction barrier).
The same distinction works for other monads, of course: `foo 1` might
return a `Parser ()`, and we have the distinction between calculating the
parser, and applying it to some input. And, in extension, with an
arbitrary `Monad` the distinction is even more evident.
So in this thread, we should be very precise which form of “calling” is
the right one.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13080#comment:20>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list