[erlang-questions] Erlang 3000?

damien morton dmorton@REDACTED
Mon Nov 17 03:05:28 CET 2008


Hmm. Took a look at a sampling of the "if" statements I found in the libraries.
Of the ones I looked at, 90% or so were your basic if/else type statement, e.g:

if
    Parent =:= self() ->
        undefined;
    true ->
        Cursor = #qlc_cursor{c = {self(), Parent}},
        fun() -> delete_cursor(Cursor) end
end,

A portion of the remaining 10% were more complicated logic, such as:

lookup_all(Key, [P | Ps]) ->
    if is_atom(P), P =:= Key -> [{Key, true} | lookup_all(Key, Ps)];
       tuple_size(P) >= 1, element(1, P) =:= Key ->  [P | lookup_all(Key, Ps)];
       true -> lookup_all(Key, Ps)
    end;

And a further portion of the remaining 10% were of the form you
described, i.e. sequences of range tests.
I see that there is an EEP for an is_between() BIF, with mention of
supporting boolean expressions of the form "A < B < C", which are a
wonderful convenience.

I find myself wondering if "case" and "if" can be unified somehow.

Consider these two hypothetical statements, which are equivalent:

A=foo(),
case
   {B,C}=A, is_list(B) -> do_list(B);
   -> do_other()
end

case foo() of
   {B,C}, is_list(B) -> do_list(B);
   -> do_other()
end

In the first statement, the attempted pattern match {B,C}=A is treated
the same as a guard. Failure to match is treated the same as a failed
guard.
In the second statement, the value to match against is implicit.

Hmm, needs more thought.





On Mon, Nov 17, 2008 at 11:44 AM, Håkan Stenholm
<hokan.stenholm@REDACTED> wrote:
>
> damien morton wrote:
>>
>> So here's a question: Are there any examples of "if" statements that would be awkward or difficult to express using a "case" statement?
>
> Conditionals that have more than 2 branches where none of them branch on patterns - e.g. something like the to_upper code below:
>
> to_upper_char(C) when is_integer(C) ->
>  if
>    $a =< C, C =< $z       -> C - 32;
>    16#E0 =< C, C =< 16#F6 -> C - 32;
>    16#F8 =< C, C =< 16#FE -> C - 32;
>    true -> C
>  end.
>
> Yes I know that this could be written as:
>
> to_upper_char(C) when is_integer(C) ->
>  case ($a =< C andaslo C =< $z) orelse
>      (16#E0 =< C andalso C =< 16#F6) orelse
>      (16#F8 =< C andalso C =< 16#FE) of
>    true  -> C - 32;
>    false -> C
>  end.
>
> but lets assume that each branch needs to do something different, so we must either use nested cases or have multiple function clauses (one for each condition) to check all the guards.
>
> "if"s tend to be convenient in numerical code - like checking for multiple numeric ranges (as above) or to avoid silly things like:
>
> case .... of
>  _ when ... -> ...
>  _ when ... -> ...
>  _ when ... -> ...
>  ...
> end
>
> instead of:
>
> if
>  ... -> ...
>  ... -> ...
>  ... -> ...
>  ...
> end



More information about the erlang-questions mailing list