[erlang-questions] Why this code not being infinite recursive?

Artie Gold the.artiegold@REDACTED
Mon Jun 17 18:45:24 CEST 2019


But, wait! Infinite (well, unbounded) recursion is a bad thing, right? At
the very least it will blow up the stack, right?

Well, yes. It would. Except for *tail recursion*. When the recursive step
is at the end of the function (and there's no lingering state to maintain),
the compiler can optimize the recursion into a simple loop. As a result you
get the cleanliness of recursive solution without having to worry about the
space needed by the calculation being unbounded.

Cheers,
--ag

On Mon, Jun 17, 2019 at 11:06 AM I Gusti Ngurah Oka Prinarjaya <
okaprinarjaya@REDACTED> wrote:

> Hi,
>
> OMG. Finally..... I know and understand how this code flowing. It takes
> days for me to understand.
> It turns out this code below:
>
> {ok, AcceptorSocket} = gen_tcp:accept(ListenSocket),
>
> is locking / blocking the execution of these lines:
>
> 1. spawn(fun() -> acceptor(ListenSocket) end),
> 2. handle(AcceptorSocket).
>
> Then, after we doing a connection to the port via telnet, the locking /
> blocking become released / unlocked / unblocked, then executing lines: 1
> and  create new process,
> lines: 2 listen / waiting the incoming message. Then make a new locking at
> the new created process for the next telnet connection. Yes this is an
> infinity recursive.
> The base case is killing main process that started from start_server/1 . exit(Pid,
> killed)
>
> Thank you :)
>
>
>
>
> Pada tanggal Jum, 14 Jun 2019 pukul 11.45 I Gusti Ngurah Oka Prinarjaya <
> okaprinarjaya@REDACTED> menulis:
>
>> Hi,
>>
>> I learn gen_tcp from learnyousomeerlangg book. I try to understand flow
>> of code below.
>> And i got confused with acceptor/1 . Because acceptor/1 call itself but
>> have no base case and just execute once. It's not usual. Why?
>> From my understanding it should be an infinity recursive.
>>
>> -module(naive_tcp).
>> -compile(export_all).
>>
>> start_server(Port) ->
>>   Pid = spawn_link(
>>     fun() ->
>>       io:format("Spawned at start_server()~n"),
>>       {ok, ListenSocket} = gen_tcp:listen(Port, [binary, {active,
>> false}]),
>>       spawn(fun() -> acceptor(ListenSocket) end),
>>       timer:sleep(infinity)
>>     end
>>   ),
>>   {ok, Pid}.
>>
>> acceptor(ListenSocket) ->
>>   io:format("I am acceptor~n"),
>>   {ok, AcceptorSocket} = gen_tcp:accept(ListenSocket),
>>   spawn(fun() -> acceptor(ListenSocket) end),
>>   handle(AcceptorSocket).
>>
>> handle(AcceptorSocket) ->
>>   inet:setopts(AcceptorSocket, [{active, once}]),
>>   receive
>>     {tcp, AcceptorSocket, <<"quit", _/binary>>} ->
>>       gen_tcp:close(AcceptorSocket);
>>     {tcp, AcceptorSocket, Message} ->
>>       gen_tcp:send(AcceptorSocket, Message),
>>       handle(AcceptorSocket)
>>   end.
>>
>> Please enlightenment
>>
>> Thank you
>>
>>
>> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>


-- 
Artie Gold, Austin, Texas
--
http://makeitsimpler.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20190617/b9825813/attachment.htm>


More information about the erlang-questions mailing list