[erlang-questions] Newbie: Is there a short-circuit for the comma operator?

James Cone <>
Wed Oct 10 09:16:13 CEST 2007


Hello KatolaZ and Raimo,

Raimo, I may have miscommunicated; I don't want the returned value; what 
I'm trying to achieve is to be tail-recursive from the middle of an if, 
where the non-recursing branches will evaluate another expression, after 
a comma-operator.  So throw/catch requires that I fail, because the 
stack frame will still be there, to catch the thrown thing.

KatolaZ, I'm trying to write the code below the way I would in C, where 
you control the nesting depth by making the control-flow leave the 
function as soon as possible.  It operates correctly in the short term, 
but is not tail-recursive, so (as expected) the interpreter runs out of 
memory.

Regards,
James.

KatolaZ wrote:
> On Wed, Oct 10, 2007 at 07:14:11PM +1300, James Cone wrote:
>> Is there an operator or function that short-circuits the comma operator, 
<snip>

> Such an operator does not exist in erlang. And I've never needed it
> :-) You should perhaps rewrite your code better. Paste it, and let's
> see where we can help.
<snip>

Raimo Niskanen wrote:
> Nope. Such a thing does not exist.
> 
> But it seems you want to do something that is well suited for throw/1.
<snip>

threadWatch(Socket, Label, Expect, Next, StatOn, StatTo, StatStart) ->
   % Expect and Next are serial numbers in our conversation with the server.
   % StatOn is the serial number on which to send the performance measure.
   % StatOn is normally false.  If it is -1, then the next send is the start
   % of the stats run.  If it is >= 0, then a stats run is in progress,
   % in which case StatStart (the start time) and StatTo (the stats process)
   % are defined.

   receive

     {tcp, error, _Reason} ->
       exit(_Reason);

     {tcp, Socket, Data} ->
       Colon = string:chr(Data, $:),
       if
         0 == Colon ->
           io:format("Unlabelled: ~p~n", [Data]),
           threadWatch(Socket, Label, Expect, Next, StatOn, StatTo, 
StatStart);
         true ->
           ok
       end,

       InLabel = string:substr(Data, 1, Colon-1),
       Rest = string:substr(Data, Colon+1),

%      io:format("Label = '~p', InLabel = '~p'~n", [Label, InLabel]),

       if
         InLabel == Label ->
           ok;
         true ->
           % This line is irrelevant; recurse now

%%%%
%%%% I believe the problem is here
%%%%
           threadWatch(Socket, Label, Expect, Next,
                              StatOn, StatTo, StatStart)
       end,

%%%
%%%  I want to avoid putting this code inside the
%%%  control structure above
%%%

       case erl_scan:string(Rest) of

         {ok, [{integer, 1, Got} |_], _} ->

%          io:format("Got = ~w, Expect = ~w~n", [Got, Expect]),

           if
             Expect == Got ->

               % This is where all of the important stuff happens.
               % Most of it is not implemented yet.

               Sendline = lists:concat([ Next,
" 
   \n"]),
               gen_tcp:send(Socket, Sendline),
%              io:format("Sent ~p", [Sendline]),
               threadWatch(Socket, Label, Expect+1, Next+1,
                           StatOn, StatTo, StatStart)
             ;
             true ->
               exit({badSequence, Data, Expect})
           end
         ;
         _ ->
           exit({malformedLine, Data})
       end

   end.



More information about the erlang-questions mailing list