[erlang-questions] tail recursion

Joe Armstrong erlang@REDACTED
Thu May 31 12:19:23 CEST 2007


On 5/31/07, Jason Dusek <jsnx@REDACTED> wrote:
> Hi All,
>
> I have a server like this:
>
> server({X, Y}) ->
>   receive
>     {update, NewState} ->
>       server(NewState);
>     {x, Client} ->
>       Client ! X,
>       server({X, Y});
>     {y, Client} ->
>       Client ! Y,
>       server({X, Y});
>   end
>   .
>
> Its tail recursive but, unfortunately, a little redundant -- I'd like
> to rewrite it like this:
>
> server({X, Y}) ->
>   receive
>     {update, NewState} ->
>       server(NewState);
>     {x, Client} ->
>       Client ! X;
>     {y, Client} ->
>       Client ! Y;
>   end,
>   server({X, Y})
>   .
>
> But I worry that the compiler and interpreter will fail to recognize
> my server as tail recursive. Will my rewrite blow the stack?

Yes you will blow the stack  - this is not tail recursive.
I'll explain why, I'll rewrite your code a bit.
suppose we have this:

> server({X, Y}) ->
>   receive
>     {update, NewState} ->
>       foo(NewState);         <--- X (I call foo here instead of server)
>     {x, Client} ->
>       Client ! X;
>     {y, Client} ->
>       Client ! Y;
>   end,
>   server({X, Y})   <--- Y

When foo returns (at point X) we call server (at Y)
So the compiler creates a new stack frame every time foo is called

Now this code *is* tail recursive if foo returns. But in your case
you called server(NewState) *which never returns*

So each pass through the code at point X builds an additional call frame
on the stack - bad news - after a while you'll run out of memory

/Joe



More information about the erlang-questions mailing list