[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