[erlang-questions] comma vs andalso
Michael McDaniel
erlangy@REDACTED
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.
>
> Robert
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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)
~Michael
More information about the erlang-questions
mailing list