[erlang-questions] tail recursion : sharing a learning and a question
David Mercer
dmercer@REDACTED
Mon Aug 17 18:25:59 CEST 2009
Amit wrote:
> 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
> for
> tail recursion?
Well, you *could* remove the try-catch and put that in a function that calls
do_maintenance/3, enabling the tail-call optimization, but that would change
the semantics of the function. I believe the function, as written, would
need to keep the stack around (that is, not optimize the tail-call - which
isn't really a tail-call, since it is within the try-catch) unless you
decide to carry around an accumulator with the state that would have been in
the stack (specifically, a list of Oldest's).
That is, whatever mechanism you use to handle errors in the error-handler
would have to be handled in a tail-call-optimizable way. I'm sure someone
else can explain it better than me, but I'm thinking of errors in the call
on the following line:
> do_maintenance(CacheSz, HKIntvl, Oldest)
Your code, as written, handles that by pushing it up to the next exception
handler on the stack. If you were to tail-call-optimize that stack frame
away, then the behavior of your program has changed.
Cheers,
David
> -----Original Message-----
> From: erlang-questions@REDACTED [mailto:erlang-questions@REDACTED] On
> Behalf Of Amit Murthy
> Sent: Sunday, August 16, 2009 8:15 AM
> To: Erlang
> Subject: [erlang-questions] tail recursion : sharing a learning and a
> question
>
> Hi,
>
> 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 though I could
> understand why.
>
>
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> %% Bad code, Bad code, Bad code, Bad code, Bad code, Bad code,
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>
> do_maintenance(CacheSz, HKIntvl, Oldest) ->
> try
> receive
> Message ->
> met_util:log_info(" pid -~p recieved unexpected
> message[~p].
> ",[self(), Message])
>
> after HKIntvl ->
> NOldest = do_cleanup(CacheSz, Oldest, 100),
> do_maintenance(CacheSz, HKIntvl, NOldest)
> end
> catch
> error:Error ->
> met_util:log("~p do_maintenance() caught exception ->
> ~p",[?MODULE, Error]),
> do_maintenance(CacheSz, HKIntvl, Oldest)
> end.
>
> %%%%%%%
>
> The right way of course is to not trap exceptions here, remove the try-
> catch
> and put the whole thing under a supervisor (with restart) behavior.
> Which is what I have done now.
>
> 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
> for
> tail recursion?
>
> Regards,
> Amit
More information about the erlang-questions
mailing list