Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir - Argument error

Tags:

elixir

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"
like image 396
sat Avatar asked Mar 12 '23 18:03

sat


2 Answers

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.

like image 147
legoscia Avatar answered Mar 19 '23 10:03

legoscia


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.

like image 30
michalmuskala Avatar answered Mar 19 '23 12:03

michalmuskala