Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why this guard don't throw exception?

Tags:

erlang

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 ??

like image 502
hu wang Avatar asked Dec 27 '22 19:12

hu wang


1 Answers

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.

like image 53
Geoff Reedy Avatar answered Jan 08 '23 12:01

Geoff Reedy