and
and or
are the oldest ones, perhaps already present in OTP R1.
That is probably why Richard Carlsson and the HiPE group suggested that Erlang needed andalso
/orelse
. I don’t remember in which release we added them. Obviously we could not remove and
and or
.
In addition to those more obvious boolean operators, there are also two language constructs that are allowed at the top-level of guards. One is ,
which is an AND operation (in a guard, it is not noticeable whether it is short-circuiting or not):
foo(A) when is_integer(A), A > 0 ->
all_is_good.
Probably less well-known is ;
, which behaves similar to orelse
:
bar(A) when is_integer(A), A > 0; is_atom(A) ->
all_is_good.
This is equivalent to:
bar(A) when is_integer(A), A > 0 ->
all_is_good;
bar(A) when is_atom(A) ->
all_is_good.
My own rules for which operators/functions to use are the following:
-
Never used
and
. (I have yet to come up with a real-world use case where I would need a strict AND in Erlang.) -
In guards, use
,
and;
if possible. Otherwise useandalso
/orelse
. -
In function bodies, use
andalso
andorelse
. -
Use
or
if you need a strict OR operation.
Use cases for a strict OR are rare, but not as rare as use cases for a strict AND. Here is one example I can think of:
foobar(A, B) when (A rem 8 =:= 0) or (B rem 8 =:= 0) ->
at_least_one_integer_divisible_by_8.
That is, A
and B
must both be integers, and at least one of them must be a multiple of 8.
UPDATE: I wrote “short-cicuiting AND” when I meant “strict AND” in the paragraph where I recommended against using and
’.
UPDATE: I wrote “short-circuiting OR” when I meant strict OR.