What did you first think of the Erlang syntax

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 use andalso/orelse.

  • In function bodies, use andalso and orelse.

  • 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.

11 Likes