CK knows Wayne

Erlang: if or case of

Published at by Christian Kruse, updated at
Filed under: erlang, functional, programming

The last few weeks I started to learn Erlang, a functional programming language designed to be very solid. This is my first functional programming language I am really learning. At the university I had a small look at Haskell, but I was never really interested in it.

After writing my first few lines of code, the following question came to my mind: when do we use case of and when do we use if? In traditional non-functional programming languages the difference was clear. But the differences blur in functional languages. So what would you write, and why? Given the following example:

case is_pid(Pid) of
    true ->
        Pid ! {send, ["QUIT :", ?QUITMSG]},
        Pid ! quit;

    false ->
        ok
end

Or

if
    is_pid(Pid) ->
        Pid ! {send, ["QUIT :", ?QUITMSG]},
        Pid ! quit;

    _ -> ok
end

Personally I would prefer the second variant, since one can see on the first look what which branch does. What do you think, and why?

Oh my god! Six comments!

Comment Feed: RSS / Atom
Gravatar

Jeena Paradies wrote

at

In the first one the expression is only evaluated once and then it's up to pattern matching. In the second one the expression in every row is evaluated and yeah it's not a real problem here but I like pattern matching.

In my head the is_pid(), or similar functions, have different cases, that is why it feels naturally to use case of. The second one seems odd, because you think "ok is_pid() returns true .. but wait there is another true, wtf?!" before you remember that it stops evaluating when the first one evaluates to true.

Another thing is that the second one seems like sequential programming "first check row 1 if it is true then ..." the case of is more like a tree which runs only the branch which is necessary.

I'm sorry I don't have a more academic answer, I hope somebody else does.

Gravatar

Tim wrote

at

I'd prefer the case construct because I like seeing explicit comparisons to explicit values, in this case the true and false pattern matching clauses. The catch-all clause in the if construct is to much indirection for my taste. In functional languages I tend to be more explicit and declarative.

I've got not so much experience reading Erlang code. But isn't there a third possibility, using guards?

Gravatar

Christian Kruse wrote

at

Hm, after trying it a guard with a function seems to be very elegant:

send_quit(Pid) when is_pid(Pid) ->
Pid ! {send, ["QUIT :", ?QUITMSG]},
Pid ! quit.

And later simply call send_quit(Pid)

Gravatar

Jeena Paradies wrote

at

But don't forget to add the other case send_quit(_) -> ok; otherwise you'll get an exception if Pid is not a pid.

Your Comment

You can use MarkDown to format your comment: *Word* for italic, **Word** for bold, images will get removed.




Because of massive spam attacks you may only post if you can answer the following question: