[erlang-questions] comma vs andalso
Thu Jul 9 17:05:25 CEST 2009
On Thu, Jul 09, 2009 at 01:28:23AM +0200, Robert Virding wrote:
> 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.
Thank you for this history and explanation, Robert. It makes it
much easier for me to remember and understand how the ';' works.
(and, by extension, the other guard separators)
More information about the erlang-questions