
Brian Denheyer wrote:
On Tue, 26 Jan 2010 22:41:44 -0800 Thomas DuBuisson
wrote: doEvent f usDelay = forkIO $ threadDelay usDelay doEvent f usDelay f
Are you sure that's right ? It seems to be a memory-gobbling infinite loop...
Why would I think that ? I think that because the following code:
import Control.Concurrent
f = putStrLn "foo"
doEvent f usDelay = do forkIO $ threadDelay usDelay doEvent f usDelay f
_really_ _does_ start to consume all of the memory on my system, that's why. I don't know why, but that's what it does on my system. It's not obvious to me that it should do that. So maybe ghci is not doing TCO.
The code you have presented at the bottom is an infinite loop that I would expect to consume all the memory on your system. That code spins at 100% busy, forking off threadDelay calls without ever stopping, and will never perform "f". Ouch -- infinite loop, and likely hugely memory-consuming (in fact, I'm not sure how the last poster didn't find that it consumed a lot of memory...). However, that code is slightly different to the original (that I have left in up the top) which had a crucial "do" missing (although you can infer it from the indentation). The original code should be: doEvent f usDelay = forkIO $ do threadDelay usDelay doEvent f usDelay f That is, the latter two lines should be inside the forkIO block, not after it. This code will wait for the given delay, then fork a new thread, then perform f. As long as f takes less time to complete than usDelay, this code should not eat memory and is quite reasonable. I hope that clears up the confusion. Neil.