[erlang-questions] case statements really required??

Joe Armstrong erlang@REDACTED
Mon Dec 7 10:45:13 CET 2009


Originally, back in the days when Erlang was sub-set of Prolog and had
only two users, Erlang had no case or if statements. These were added
as a convenience - before this there were only pattern matching
clauses.

It's easy (though tedious) to transform code with a case statement
like this:

     foo(X, Y) ->
         A = 1,
	 B = 2,
	 case X of
	    a -> A + Y;
	    b -> B + Y
	 end.

Into pure pattern matching code, like this:

   foo(X, Y) ->
        A = 1,
	B = 2,
        foo1(X, Y, {A,B})

   foo1(a, Y, {A,B}) ->  A + Y;
   foo1(b, Y, {A,B}) ->  B + Y.

The reason why case statements are nice is that the variable bindings
created before 'case' was evaluated are available inside the body of
the case statement (in my example the variables A and B).

Without using a case statement these variable must be explicitly
imported into the pattern matching code (these appeared as the tuple
{A,B} in the call to foo1.

Doing this correctly for all edge cases, when the function is complex
and has multiple clauses is "a wee bit tricky (TM)" that's why the
compiler does it for you.

In fact what happens is exactly the opposite - Erlang pattern matching
code is transformed to an internal form (which has a case statement)
and is then optimized.

Note the wording "and is then optimized." The question "are case/if
statements more efficient than explicit function clauses?" is often
asked.

The answer is "it probably makes no measurable difference." In many
cases the same logic expressed with a case statement or with pure
pattern matching code results in identical VM code. If you can
outsmart the pattern matching compiler then please tell us - it's
probably a bug.

In choosing between case/if and pure functions always choose the most
beautiful code. One day you will have to read and maintain your code
so write beautiful code with accurate descriptive function names.

**Do not try to optimize your code** - that's the job of the pattern
matching compiler. Write simple clear patterns, this gives the
compiler the best chance to optimize things. If you have written
simple clear patterns that you think should be efficient and find out
that they are not efficient then please tell us - it might be a edge
case in the pattern matching compiler that we need to fix to make
better code.

While we're on the subject remember that Erlang is built from expressions
and every expression must have a value.

That's why case and if should always return a value

       X = if
             Y > 0 -> ..
           end

is most likely to be bad Erlang code, since X has no value if Y =< 0.

The equivalent *is* legal in C - because C is a *statement* language
and each statement is evaluated for its side effects - but it is not
legal in Erlang (unless you really want your program to crash).

If if you really want to crash then you should write:

      X = if
             Y > 0 -> ...
             true  -> exit(...)
          end

Why? - because when you read the code ten years later you might
understand it. If you miss the explicit exit you will probably wonder
why there was no true branch in the if statement.

/Joe



On Mon, Dec 7, 2009 at 2:29 AM, Richard O'Keefe <ok@REDACTED> wrote:
>> kiran wrote:
>>>
>>> hi,
>>> is it good to use case statements in functional language..  according to
>>> me .. pattern matching-functions could do the task.
>>> any commnets??
>
> Multiclause pattern-matching functions and case expressions do exactly
> the same thing; except for the error message you get when there is no
> match either can be trivially converted to the other.
>
> You should consider questions like
>
> - can you give this part of your program a meaningful name?
>  [If so, it might make a good function.]
>
> - would this part of your program be useful elsewhere,
>  perhaps with a few constants replaced by variables?
>  [If so, it might make a good function.]
>
> - is the normal flow of your code obscured by bulky code that
>  could be moved elsewhere?
>  [If so, it might be useful to split it out as a function, or
>   you could use a literate programming tool, but in either case
>   you'll have to find a good name for it].
>
>
>
> ________________________________________________________________
> erlang-questions mailing list. See http://www.erlang.org/faq.html
> erlang-questions (at) erlang.org
>
>


More information about the erlang-questions mailing list