
#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