[erlang-questions] comma vs andalso

Robert Virding rvirding@REDACTED
Thu Jul 9 01:28:23 CEST 2009

2009/7/8 Thomas Lindgren <thomasl_erlang@REDACTED>

> ----- Original Message ----
> > From: Richard O'Keefe <ok@REDACTED>
> >
> > Let's take two apparently similar functions:
> >
> > f(X) when is_atom(element(3, X)) ; true -> 42.
> >
> > g(X) when is_atom(element(3, X)) orelse true -> 42.
> >
> > By actual test, f(99) -> 42.
> > By actual test, g(99) -> a function_clause exception.
> >
> > That is, in a guard, an expression using 'andalso' or
> > 'orelse' is still an expression, and if an exception
> > occurs in the left-hand operand, the whole expression
> > is still skipped.
> ....
> > I conclude that
> > (1) you had best be EXTREMELY cautious about using 'andalso'
> >     and 'orelse' in guards; they are NOT drop-in replacements
> >     for ',' and ';', and
> > (2) it is long past time that Erlang allowed nested use of
> >     ',' and ';' in guards.
> Guards are an awful mess in Erlang. I'd be quite surprised if the above
> difference in behaviour was intentional. If so, what possible purpose does
> it serve?

The above difference is intentional! There is one fundamental and important
difference between using orelse/or or ';' and that is in the case of
exceptions. If an exception occurs in the case:

G1 ; G2 ; G3 ; ...

say in G1 then G1 will fail and G2 will be attempted, as an exception is
equivalent to failure. This is logical as they are separate guards. However,
if an exception occurs in:

G1 orelse G2 orelse G3 ...

in G1 again then the WHOLE guard expression will fail, G2 will never be
tried as it is part of the same expression. This IS intentional as using ';'
is exactly equivalent to separate clauses with the same RHS. So

f(...) when G1 ; G2 ; G3 -> <RHS>.

is the same as:

f(...) when G1 -> <RHS>;
f(...) when G2 -> <RHS>;
f(...) when G3 -> <RHS>.

This functionality was added for just this case. There is logic in the
madness. It was simple before with only simple guard tests, it only became
confusing when logical expressions were allowed in guards. They are
practical but were only added later, THEY are the odd man out. This is also
why originally there were no problems with type tests without is_ in guards.

Guards were always meant to be part of pattern matching and no more.


More information about the erlang-questions mailing list