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