Consider the following code:
-module(abc).
-export([f/1]).
f(X) when (X==0) or (1/X>2) -> X+100;
f(X) ->X.
and abc:f(0). get result 0 , but why 1/X don't throw exception ??
The Guard Sequences section of the erlang documentation says:
If an arithmetic expression, a boolean expression, a short-circuit expression, or a call to a guard BIF fails (because of invalid arguments), the entire guard fails. If the guard was part of a guard sequence, the next guard in the sequence (that is, the guard following the next semicolon) will be evaluated.
In other words, exceptions in guards are treated as if the guard returned false without raising the exception. The evaluation of guards is slightly different than that of normal erlang expressions.
When you call abc:f(0)
, the expression (0==0) or (1/0>2)
is evaluated. This expression "fails" because of division by zero so the guard does not match and the next clause is evaluated to give the answer of 0
.
If you want this case to return 100
you have two options: use a guard sequence or use short circuit boolean operators. These would be
f(X) when X==0; 1/X>2 -> X + 100;
f(X) -> X.
and
f(X) when X==0 orelse 1/X>2 -> X + 100;
f(X) -> X.
respectively. Both ways of writing it will evaluate X==0
as a separate exception and not execute 1/X>2
if the result is true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With