[erlang-questions] Newbie: Is there a short-circuit for the comma operator?
James Cone
jcone@REDACTED
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