How to write "a==b ? X : Y" in Erlang, in other words how to write a C-style ternary operator?
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.
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")]).
If you're asking how to write something like A == B ? X : Y
as an if
expression, it's
if
A == B ->
X;
true -> % "true" means "else" here
Y
end
You can also write it as a case
expression:
case A == B of
true ->
X;
_Else ->
Y
end
or
case A == B of
true ->
X;
false ->
Y
end