1 Dec 2002 05:53
RE: Running out of memory in a simple monad
Richard Uhtenwoldt <ru <at> river.org>
2002-12-01 04:53:28 GMT
2002-12-01 04:53:28 GMT
David Bergman writes: >It is easy to get the feeling that the recursive call in > > recurse = do > f x > recurse > >is the last one, but this is just an illusion of the iterative layout of >"do". Sometimes the monads lure us into old iterative thought >patterns... > >Taking away the syntactic sugar, we end up with > > recurse = f x >> recurse > >This reveals the fact that there can be no last call optimization, >because the last call is ">>". What do you mean by this? Do you mean that that an implementation cannot execute arbitrarily many iterations/recursions of that last loop/definition in constant space? If that's what you mean, you are wrong. GHC does that. The IO monad would be pretty damned useless for actual work if implementations did not do that! Even if we replace the (>>) with a (:) as the "main operator"/"last call" of the loop, the result can execute in constant space because of optimizations.(Continue reading)
Actually, you are right in that the "last call optimization" is not
vital in most call-by-need scenarios, since both (the implicit) call
stack and data structures are often consumed as generated, and the GC
can reclaim the thunks. Note: In an unoptimized scenario, such as with
Hugs, you do indeed run out of memory in your "loop" (after some 40000
iterations) not having the recursion in the last call. Even loops not
constructing cons cells do, such as
loop 0 = return ()
loop n = do { print n; loop (n-1) } -- print n >> loop (n-1)
main = loop 50000
(you see Hugs die after some 25000 iterations...)
Sorry about the over-simplification, but I wanted people to not forget
that the "do" is just syntactic sugar...
Thanks,
David
-----Original Message-----
From: Richard Uhtenwoldt
RSS Feed