1

I am new to Elixir but I couldn't find an answer to my question. Here are some examples I have entered to iex.

expression   result
9 || true    9
true || 9    true
9 && true    true
true && 9    9

So, when there is an || it will evaluate to first argument, and && to last when one argument is not boolean. How are || and && implemented? Why are they returning those results?

sininen
  • 503
  • 1
  • 6
  • 20
  • 8
    This is true in *most* languages that implement short-circuiting boolean logic without forcing the results to a narrowly-constrained boolean type. If the first side of the branch is true, you just return it exactly as it is, otherwise you return the other side; that way you preserve not only the truthiness logic as-desired, but also the exact values. – Charles Duffy May 13 '19 at 17:50
  • 1
    https://stackoverflow.com/questions/5417969/why-dont-logical-operators-and-always-return-a-boolean-result is a JavaScript equivalent to the question – Charles Duffy May 13 '19 at 17:52
  • https://stackoverflow.com/questions/9797522/how-do-and-and-or-act-with-non-boolean-values-in-python is a Python equivalent to the question. – Charles Duffy May 13 '19 at 17:53
  • The key point is that when `X` is truthy, `X || Y = X` rather than `true`. – cmbuckley May 14 '19 at 13:31

3 Answers3

4

This is a common language facility in the context of short-circuiting boolean logic. To throw out pseudocode of some example cases where it's useful:

need_a_number() && calculate_number() # do the expensive calculate_number() call, and evaluate to
                                      # its result, only if need_a_number() is truthy.

get_a_string() || "default string"  # returns "default_string" if get_a_string() is falsey

If your && and || returned only boolean values, you wouldn't be able to both branch and calculate in a single operation.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
3

While answer by Charles is correct it do not tell whole story. In general Elixir have 2 different sets of operators for working on "booleanish" values:

  • && and || - these works on all types, and literally are shortcuts for:

    case left do # equivalent to left && right
      x when x in [nil, false] -> x
      _ -> right
    end
    
  • and and or which works only on true and false atoms and will fail with BadBooleanError when provided anything else.

And as it was said both of these operators are short-circuiting, which mean that these will cut computation as soon as the result is obvious.

Hauleth
  • 22,873
  • 4
  • 61
  • 112
  • 1
    The code example is great, but the comment is confusing, and I have no idea what it means --(Oh! Now I do). How about putting the comment above the code and shortening it to merely `left && right`. – 7stud May 14 '19 at 14:51
-2

Programming languages implement the concept of truthy and falsy value types in order to use them in boolean logic. Some values are considered to be false and others are considered to be true when used in boolean operations and the fact that the last value of the function -- or expression -- is returned, allows us to short-circuit and branch our functions as mentioned in the previous answer.

This is true for every language I know.

In Elixir (1.7.3 compiled with Erlang/OTP 21) I think we have a consistent behaviour, even with number Zero:

(0 || false) == 0 # true
(0 || false) === 0 # true

And just to compare, in Javascript (Google Chrome v74):

(0 || false) == 0 // true
(0 || false) === 0 // false
hisa_py
  • 929
  • 11
  • 16