The If expression

Jay Nelson jay@REDACTED
Thu Apr 22 07:06:31 CEST 2010


Henning Deidrich offered one-armed ifs to rewrite:

 > (4)
 >        glist() ->
 >            spawn(fun() -> glist_loop([], nil, nil) end).
 >
 >        glist_loop(List, PrevCaller, Return) ->
 >
 >            % call back to originally caller, to deliver result.
 >            % (so: not on very first call, if no Caller is given,  
or it
 >            % died (?) in the meantime.
 >            if
 >                 is_pid(PrevCaller) ->
 >                    vecho(?D4, "call ~p ~p", [PrevCaller, Return]),
 >                    PrevCaller ! Return;
 >         >>>     true -> nil
 >            end,
 >
 >            receive
 >                { add, Element, Caller } -> glist_loop([Element |  
List],
 >        Caller, ok);
 >                { drop, Key, Caller } ->
 >        glist_loop(lists:keydelete(Key,1,List), Caller, ok);
 >                { get, Key, Caller } -> glist_loop(List, Caller,
 >        lists:keyfind(Key,1,List));
 >                E -> throw(E)
 >            end.


glist_loop(List, PrevCaller, Return) when is_pid(PrevCaller) ->
   vecho(?D4, ...),
   PrevCaller ! Return,
   glist_response(List, PrevCaller, Return);
glist_loop(_List, PrevCaller, _Return) ->
   {error, {not_a_pid, PrevCaller}}.

Your drop through branch looks like it gets caught in a receive  
statement with no timeout, here I explicitly return an error value.   
You could choose to do something different.

glist_response(List, PrevCaller, Return) ->
    receive
       ... same as above ...
    end.


Sometimes factoring out a different function gives you the pattern  
match that you need to break out the cases.  Don't forget that when  
clauses can be as useful as argument values to differentiate the cases.

jay



More information about the erlang-questions mailing list