Can someone please help explain why we get the argument error? Are we not supposed to check for truthyness this way? On Elixir 1.3
iex(1)> true and true
true
iex(2)> "true"
"true"
iex(3)> true
true
iex(4)> true and "true"
"true"
iex(5)> "true" and true
** (ArgumentError) argument error: "true"
Elixir has two sets of boolean operators:
or
, and
and not
in principle require their arguments to be actual booleans, i.e. the atoms true
and false
||
, &&
and !
accept arguments of any types, and check "truthiness".Though in fact, or
and and
only check the type of the first argument. For any value of x
, the expressions false or x
and true and x
will simply return x
. This might seem confusing, but it allows using or
and and
as the last expression in a recursive function without impeding tail recursion. For example, consider this function, which checks whether all elements in a list are equal to 42:
def x([]) do
true
end
def x([h|t]) do
h == 42 and x(t)
end
Because and
permits tail recursion, this function will run in constant stack space. If and
would check the type of its second argument, the function would have to make a normal call one stack frame "deeper", and upon return perform the check and return the value.
The "wordy" boolean operators - and
, or
and not
are strict - they expect all values to be strictly boolean. The symbolic operators - &&
, ||
and !
- operate on the "truthiness" instead of strict booleans.
Because all booleans operators are short-circuiting they will actually only check the first argument for being strictly boolean, but I discourage using them with non-booleans.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With