Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write "a==b ? X : Y" in Erlang, in other words how to write a C-style ternary operator?

Is there a good way to write code like this in Erlang?

A == B ? X : Y

below is ruby-style code. This is also known as a ternary operator.

like image 241
why Avatar asked May 23 '11 04:05

why


2 Answers

We use macro like this:

-define(IF(Cond,E1,E2), (case (Cond) of true -> (E1); false -> (E2) end)).

Then in your code you write:

io:format("~s~n", [?IF(a==b, "equal", "not equal")]).
like image 50
nivertech Avatar answered Nov 16 '22 03:11

nivertech


Explanation

The reason the ternary operator _ ? _ : _ exists in many languages is due to the fact that they have two syntactic classes: Statements and Expressions. Since if-then-else constructions usually belong the the statement-class, there is no way to get that working for when you are entering an expression. Hence you add the _ ? _ : _ operator to the expression class.

As another post states, you can take a == b ? true : false and just write a == b, but that does not explain the general case where we may have a == b ? X : Y for arbitrary expressions X and Y. Also note that a == b is always false in Erlang, so you could argue that the real thing to do is to replace the whole expression with false.

Luckily, Erlang, as is the case for most functional languages, have one syntactic class only, expressions. Hence you can use case a == b of X -> ...; Y -> ... end in any place in a function, other expressions included. In other words, the ternary _ ? _ : _ operator is redundant in Erlang since the case already works.

An example:

Suppose we are to return a simple proplist and we have some computation we need to do

  f() ->
    case a == b of
          true -> 
           [{a, 3},
            {b, <<"YE">>},
            {c, 7}];
          false ->
           [{a, 3},
            {b, <<"YE">>},
            {c, "HELLO!!!"}];
    end.

But since the case construction is an expression, we can just inline it:

  f() ->
    [{a, 3},
     {b, <<"YE">>},
     {c, case a == b of
          true -> 7;
          false -> "HELLO!!!"
         end}].

and be done with the thing.

Why I am not advocating the use of IF

the if .. end construction in Erlang is usually not what you want. You want to scrutinize a value a == b in this case and it can yield one of two outputs true or false. In that case the case-expression is more direct. The if is better used if you have to check for multiple different tests and pick the first matching, whereas we only have a single test to make here.

like image 26
I GIVE CRAP ANSWERS Avatar answered Nov 16 '22 03:11

I GIVE CRAP ANSWERS