
Simon writes:
You can paraphrase this in Haskell, in the IO monad, like this:
loop = do { a <- get_input; if (a == gET_OUT) then return () else loop; }
In GHC this won't grow any stack each time around the loop, even with optimisation off. It depends on the actual implementation of the IO monad, but I imagine the other Haskell implementations will also have this property.
It's worth adding that Mark's initial code,
f a
| a == GET_OUT = a
| otherwise = f ( g a)
will also not grow the stack, on any decent Haskell implementation. Tail recursion is always implemented properly here - tail recursion simply means that the result of the function is the result of the recursive call to the function, i.e., no more computation need be done once the result of the recursive call is known.
http://wombat.doc.ic.ac.uk/foldoc/foldoc.cgi?tail+recursion
Of course, laziness may well bite you and you may run out of *heap*, but that's another story for another evening!
--KW 8-)
--
Keith Wansbrough