Alexein
Alexein

Reputation: 686

Erlang if else statement

Im trying to do a method where it checks the value of two atoms, if they are equivalent to each other it gonna say it's false and the other way around, if they aren't equivalent it's gonna be true.

my code looks like this:

b_not(X, Y) ->
if
    X=:=Y ->
        false;
else
        true;
end.

Here the name of my method is "b_not" which stands for boolean_not. and I check with the if-statement if X is exactly equal to Y it gonna say false. Ok that part alone I could do. But my problem comes to when I try to make the else-statement. I don't seem to get this part, I tried to search around on the internet, but I don't seem to get it. So if you could tell me how the if-else-statement works in Erlang, I would be pleased!

Thanks Alexein!

Upvotes: 0

Views: 2701

Answers (2)

Emil Vikström
Emil Vikström

Reputation: 91983

That is what the =/= operator do!

b_not(X, Y) -> X =/= Y.

I can understand your confusion about if statements. You should really read about if and guards in the manual because if do not work as in many other languages. This is one way of achieving it in Erlang (but "if true then true" is kind of an anti-pattern so don't do exactly this):

if
  X =/= Y -> true;
  X =:= Y -> false
end

Note that when one of the guards (to the left of the arrow) evaluates to the true atom the if statement will evaluate to the expression following that arrow. There is no else clause but you can invent one yourself by putting true before the arrow:

if
  X =/= Y -> true;
  true -> false
end

This is not very intuitive, especially not for people from other language backgrounds, and I suppose that is one reason pattern matching are often preferred over if expressions.

For completeness, read up on the case expression as well. It is meant for doing pattern matching inside the body of a function:

case X of
  Y -> false;   % X equals Y
  _ -> true     % Everything else, i.e., X is not Y
end

Upvotes: 8

macintux
macintux

Reputation: 894

I'm relatively new to Erlang, but the language isn't designed to work in the way you describe. There is an if construct, but I don't believe it's used often.

Instead, what you describe can be achieved like this using pattern matching:

b_not(_X, _X) -> false;
b_not(_, _) -> true.

The underscore pattern match indicates a wildcard; a pattern match which is preceded by an underscore means that you do not intend to use the value in the function, but you do care about the matching itself.

So the first pattern match means "I don't intend to use _X for anything, but both values must be the same."

The second pattern match means "These are throwaway values and can be anything at all."

Many functions are defined with multiple argument patterns, and Erlang decides for you which of the patterns matches the invocation.

In this case, if an identical value is passed twice, whether that be an integer, atom, list, or any other type, the first pattern will be matched and false will be returned. Otherwise, the second pattern is matched.

This only works because the patterns are defined in this order; if they were reversed, any arguments would result in true.

Illustrations:

16> foo:b_not(3, 3).
false
17> foo:b_not(3, 4).
true
19> foo:b_not(3, 3.0).
true
20> foo:b_not(match, match).
false
21> foo:b_not(match, nomatch).
true
22> foo:b_not([1, 2], [1, 2]).
false
23> foo:b_not([1, 2], [1, 2, 3]).
true

Upvotes: 8

Related Questions