[erlang-questions] Reading, Learning, Confused
Richard A. O'Keefe
ok@REDACTED
Mon Jul 21 02:26:02 CEST 2008
On 20 Jul 2008, at 1:26 am, Sean Allen wrote:
> by a small bit of example code in Programming Erlang related to guards
> and short circuit booleans:
>
> f(X) when (X == 0) or (1/X > 2) ->
> ...
>
> g(X) when (X == 0) orelse ( 1/X > 2) ->
> ...
>
> The guard in f(X) fails when X is zero but succeeds in g(X)
>
> Can someone explain why?
This is a perfect example of why 'or' and 'orelse' should NEVER be used
in guards (and ditto for 'and' and 'andalso'.
By the way, I find Pascal-inspired otiose parentheses around
comparisons ugly and confusing.
Let's do this the old way:
f(X) when X == 0 ; 1/X > 2 ->
The execution of a guard sequence stops when
- all guard conjunctions have been tested or
- one guard conjunction succeeds.
So 1/X > 2 is only tested when the X == 0 test fails.
Now let's do it with 'orelse'.
f(...) when G1 orelse G2 orelse ... orelse Gn ->
is a long-winded way to write
f(...) when G1 ; G2 ; ... ; Gn ->
and works the same way: keep on testing until something
succeeds, then *stop*. This is commonly called 'short-
circuit evaluation', and it is just exactly the same as
C's (or Haskell's) "||", except for the spelling.
'or', on the other hand, acts just like '+'. It always
evaluates both arguments. (So does 'and'.) Think of it
as being like C's "|" in this respect. There are very
very very very few known good uses for 'or'.
So whether X is 0 or not,
X == 0 or 1/X > 2
will evaluate BOTH X == 0 AND 1/X > 2. When X is 0,
this would raise an exception in an expression, but
things that would raise an exception in an expression
just make a guard fail.
Bottom line:
DON'T use 'or' or 'and' ANYWHERE.
DON'T use 'orelse' or 'andalso' in guards
but instead stick to ';' and ','.
More information about the erlang-questions
mailing list