[erlang-questions] Erlang elseif

Daniel Rönnqvist <>
Fri Nov 21 08:37:59 CET 2008


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 <>

> >> 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
> 
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20081121/a07a610f/attachment.html>


More information about the erlang-questions mailing list