Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang style - case vs function pattern matching

I've got to the stage where I've written quite a bit of Erlang code now, and I can see some style (bad or good) creeping into the way I've been writing it. This particular idiom I'd like some opinion on - is it better (more readable/faster/whatever) to convert case style statements to function pattern matching?

E.g.

Compare (a contrived example)

case {Size > 100000, Type} of
    {true, ets } ->
         %% Do something to convert to dets
         something;
    {false, dets} ->
         %% do something to convert to ets
         somethingelse;
    _ ->
         ignoreit
end;

with

...
maybeChangeStorage(Size, Type)
...

maybeChangeStorage(Size, ets) when Size > 10000 ->
   something;
maybeChangeStorage(Size, dets) when Size < 10000 ->
   somethingelse;
maybeChangeStorage(_,_) ->
   ignoreit.

I prefer the latter in most cases but I'd be interested in other opinion.

like image 519
Alan Moore Avatar asked Jun 26 '09 19:06

Alan Moore


People also ask

What is pattern matching in Erlang?

Pattern matching occurs when evaluating a function call, case- receive- try- expressions and match operator (=) expressions. In a pattern matching, a left-hand side pattern is matched against a right-hand side term. If the matching succeeds, any unbound variables in the pattern become bound.


1 Answers

The second is the preferred way especially if you can keep the clauses to a single line:

maybeCngStor(Sz, ets)  when Sz > 10000 -> something;
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse;
maybeCngStor(_,_)                      -> ignoreit.

Makes it very easy to read and reason about. Always choose the style that will be easiest to read in the future. Often you find a set of clauses where one is a 10 liner and the rest are one lines only - break out the long one to a function:

maybeCngStor(Sz, ets)  when Sz > 10000 -> something;
maybeCngStor(Sz, dets) when Sz < 10000 -> somethingelse();
maybeCngStor(_,_)                      -> ignoreit.

somethingelse() ->
   (...)
   Return.

Little things like laying out the clauses to align them and using short variable names matter - but don't fall into the trap of changing everything to P, Q, R.

A good trick if you use records a lot is to match out the records to short variables:

#record{foo = F, bar = B, baz = Bz} = Parameter

This gives you short variable names that make sense when you parachute into the function from 10,000 feet looking for a bug next Christmas. F obviously is a Foo, etc, etc...

like image 112
Gordon Guthrie Avatar answered Sep 23 '22 02:09

Gordon Guthrie