[erlang-questions] tail recursion : sharing a learning and a question
Mon Aug 17 20:13:49 CEST 2009
Thanks Richard. A pretty neat solution and a very clear explanation.
On Mon, Aug 17, 2009 at 10:12 PM, Richard Carlsson <richardc@REDACTED>wrote:
> Amit Murthy wrote:
>> I just learned that every iteration of the below code goes onto the stack.
>> The evaluation of the "catch" has something to do with it
>> do_maintenance(CacheSz, HKIntvl, Oldest) ->
>> after HKIntvl ->
>> do_maintenance(CacheSz, HKIntvl, NOldest)
>> error:Error ->
>> do_maintenance(CacheSz, HKIntvl, Oldest)
>> The right way of course is to not trap exceptions here, remove the
>> and put the whole thing under a supervisor (with restart) behavior.
>> Which is what I have done now.
> It would be sufficient to rewrite it like this:
> do_maintenance(CacheSz, HKIntvl, Oldest) ->
> after HKIntvl ->
> NewOldest -> do_maintenance(CacheSz, HKIntvl, NewOldest)
> error:Error ->
> do_maintenance(CacheSz, HKIntvl, Oldest)
> The "protected" part of the code is the one between 'try' and 'of',
> or between 'try' and 'catch' if there is no 'of' section. In the
> protected part, tail recursive calls are not possible. (The call
> in the 'catch...end' section, however, is tail recursive here.)
> Basically, what your version of the code says is "if the recursive
> call fails, we must catch that before we are allowed to exit from
> the current call". The rewritten version above says "do the receive
> and the log_info or cleanup, and catch any errors in that part (but
> only in that part), then do a tail call to exit from the current call".
> Would still like to know as to why the try-catch ends up killing tail
>> recursion. Can't the compiler catch this (pun intended) and optimize it
>> tail recursion?
> No, because what the code says is that it should catch errors that may
> happen in the recursive call, and handle the errors using the context of
> the current call (e.g., the current value of Oldest). This means that
> the compiler must keep the stack entry for the current call until the
> recursive call has finished. Hence, no tail recursion optimization.
More information about the erlang-questions