[erlang-questions] Erlang elseif

Joseph Wayne Norton norton@REDACTED
Fri Nov 21 08:59:20 CET 2008


Daniel -

You can implement

   If <expression1> == true then <result1>
   elseif <expression2> then <result2>
   else <result3>

in erlang as follows

if <expresson1> == true ->
     <result1>;
    <expression2> ->
     <result2>;
    true ->
     <result3>
end.



On Fri, 21 Nov 2008 16:37:59 +0900, Daniel Rönnqvist  
<kdronnqvist@REDACTED> wrote:

> I am merely trying to figure out why this simple logical control  
> structure
> don't exist;
>
> If <expression> == true then <expression>
> elseif <expression> then <expression>
> else <expression>
>
> I know I can get lots and lots of good ideas on how to do this if I were  
> to
> give you my whole real example but that is not my point. I am narrowing  
> it
> down to this because THIS is what I want to discuss.
>
> IMHO, it shouldn't be that hard for the compiler/precompiler to "rewrite"
> another control structure as nested case statements which would work as a
> general solution, be very fast with less and arguably more readable code.
>
> BR,
> Daniel Rönnqvist
>
> 2008/11/21 Richard O'Keefe <ok@REDACTED>
>
>> >> this but I could not find anything that answered my question. The
>> >> thing is
>> >> that I want a general way to branch the execution of my code based
>> >> on the
>> >> result on an expression. Very similar to how if works but I want to
>> >> be able
>> >> to test expressions and not only guards. If you're thinking "then
>> >> you have
>> >> case" now look below at function elseif2() and you'll see my point.
>>
>> Given that we have length(List) in guards, which definitely breaks
>> the "guards are fast" guideline, it would be tempting to allow
>> member(Term, List) in guards as well.
>> >> 42> e:elseif4($Q).
>> >> Member of capital
>> >>
>> >> -define(CAPS, "QWERTY").
>> >> -define(SMALL, "qwerty").
>> >> -define(NUMS, "123456").
>> >>
>> >> %% The wierd not-so-Erlang way
>> >> elseif1(A) ->
>> >>   lists:member(A,?CAPS)
>> >>       andalso begin
>> >>                   io:format("Member of capital\n"),
>> >>                   true
>> >>               end
>> >>       orelse
>> >>       lists:member(A,?SMALL)
>> >>       andalso begin
>> >>                   io:format("Member of small\n"),
>> >>                   true
>> >>               end
>> >>       orelse
>> >>       lists:member(A,?NUMS)
>> >>       andalso begin
>> >>                   io:format("Member of nums\n"),
>> >>                   true
>> >>               end
>> >>       orelse
>> >>       io:format("Not a member").
>>
>>         ei(Letter) when is_integer(C) ->
>>            io:format(eic(Letter)).
>>
>>        eic(C) when C == $Q ; C == $W ; C == $E
>>                   ; C == $R ; C == $T ; C == $Y
>>            -> "Member of capital\n";
>>        eic(C) when C == $q ; C == $w ; C == $e
>>                  ; C == $r ; C == $t ; C == $y
>>            -> "Member of small\n";
>>        eic(C) when C == $1 ; C == $2 ; C == $3
>>                  ; C == $4 ; C == $5 ; C == $6
>>            -> "Member of nums\n";
>>        eic(_)
>>            -> "Not a member\n".
>>
>> In fact, I'd probably do it with two tables:
>>
>>        ei(Letter) -> io:format(eim(eic(Letter))).
>>
>>        eic($Q) -> large;
>>        eic($W) -> large;
>>        eic($E) -> large;
>>        eic($R) -> large;
>>        eic($T) -> large;
>>        eic($Y) -> large;
>>        eic($q) -> small;
>>        eic($w) -> small;
>>        eic($e) -> small;
>>        eic($r) -> small;
>>        eic($t) -> small;
>>        eic($y) -> small;
>>        eic($0) -> digit;
>>        eic($1) -> digit;
>>        eic($2) -> digit;
>>        eic($3) -> digit;
>>        eic($4) -> digit;
>>        eic($5) -> digit;
>>        eic($6) -> digit;
>>        eic(_)  -> other.
>>
>>        eim(large) -> "Member of capital\n";
>>        eim(small) -> "Member of small\n";
>>        eim(digit) -> "Member of nums\n";
>>        eim(other) -> "Not a member\n".
>>
>> I know the table is large, but if you want to classify this way
>> here, you may well want to classify the same way somewhere else.
>> I like this approach a lot: it's dead simple and it's fast.
>>
>> Let's look at the pure 'case' version:
>>
>>        ei(A) ->
>>            M = case lists:member(A, ?CAPS)
>>                  of true -> "Member of capital\n"
>>                    ; false ->
>>                     case lists:member(A, ?SMALL)
>>                        of true -> "Member of small\n"
>>                          ; false ->
>>                          case lists:member(A, ?NUMS)
>>                             of true -> "Member of nums"
>>                             ; false -> "Not a member\n"
>>                          end
>>                     end
>>                end,
>>            io:format(M).
>>
>> Suppose the syntax were extended ever-so-slightly to
>> include an equivalent of Algol 68's "ouse":
>>
>>        ei(A) ->
>>            M = case lists:member(A, ?CAPS)
>>                  of true -> "Member of capital\n";
>>             or case lists:member(A, ?SMALL)
>>                  of true -> "Member of small\n";
>>             or case lists:member(A, ?NUMS)
>>                  of true -> "Member of nums\n"
>>                   ; false-> "Not a member"
>>                end,
>>            io:format(M).
>>
>> Here the sequence "; or case" is equivalent to
>> "; _ -> case" PLUS an extra "end" at the end.
>>
>> Now do
>>        -define(IF, case).
>>        -define(THEN, of true ->).
>>        -define(ELIF, ; or case).
>>        -define(ELSE, ; false ->).
>>        -define(END, end).
>> and
>>
>>        ei(A) ->
>>            M = ?IF   lists:member(A, ?CAPS)  ?THEN "Member of capital\n"
>>                ?ELIF lists:member(A, ?SMALL) ?THEN "Member of small\n"
>>                ?ELIF lists:member(A, ?NUMS)  ?THEN "Member of nums\n"
>>                ?ELSE                               "Not a member"
>>                ?END,
>>            io:format(M).
>>
>> I'm not actually advocating the use of ?IF, ?THEN, ?ELIF, ?ELSE, ?END;
>> I mention them merely to clarify that the "ouse" approach gives you
>> something structurally similar to if-then-elif-else.
>> I _do_ think that something along the lines of "; or case" would be
>> nice, but as it stands it would be far too error-prone.
>>
>> Every time something like this comes up I say the same thing:
>>
>>        Show us some real code, not a toy example.
>>
>> With real code, there is almost always a better way.
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://www.erlang.org/mailman/listinfo/erlang-questions
>>



-- 
norton@REDACTED



More information about the erlang-questions mailing list