Question(s)
In Lua:
local a = b or 0
local a = b and 1 or 0
Where b can be of any type.
What are the differences in between the lines of code? And in what cases would I use one or the other?
Context
I have to port existing Lua code to another service and I ran into a problem understanding why in some parts of the code (I'm not a Lua developer), a variable gets assigned to one and in other parts of the code, a variable gets assigned to another. The variable on the right hand side is an input parameter and I have no way of knowing the intended type.
What I have tried
I looked online for Lua documentation on this and I couldn't find any clear answers on this. I ran my own test:
local a1;
print(type(a1)) -- nil
local b1 = a1 or 0
print(b1 .. " " .. type(b1)) -- 0 number
local c1 = a1 and 1 or 0
print(c1 .. " " .. type(c1)) -- 0 number
local a2 = 5
print(type(a2)) -- number
local b2 = a2 or 0
print(b2 .. " " .. type(b2)) -- 5 number
local c2 = a2 and 1 or 0
print(c2 .. " " .. type(c2)) -- 1 number
local a3 = 0
print(type(a3)) -- number
local b3 = a3 or 0
print(b3 .. " " .. type(b3)) -- 0 number
local c3 = a3 and 1 or 0
print(c3 .. " " .. type(c3)) -- 1 number
local a4 = false
print(type(a4)) -- boolean
local b4 = a4 or 0
print(b4 .. " " .. type(b4)) -- 0 number
local c4 = a4 and 1 or 0
print(c4 .. " " .. type(c4)) -- 0 number
local a5 = true
print(type(a5)) -- boolean
local b5 = a5 or 0
print(b5 .. " " .. type(b5)) -- error, concatenating boolean to string
local c5 = a5 and 1 or 0
print(c5 .. " " .. type(c5)) -- 1 number
local a6 = "str"
print(type(a6)) -- string
local b6 = a6 or 0
print(b6 .. " " .. type(b6)) -- str string
local c6 = a6 and 1 or 0
print(c6 .. " " .. type(c6)) -- 1 number
local a7 = ""
print(type(a7)) -- string
local b7 = a7 or 0
print(b7 .. " " .. type(b7)) -- string
local c7 = a7 and 1 or 0
print(c7 .. " " .. type(c7)) -- 1 number
It seems to me that the only use case for the line of code with the and conditional is when b is of boolean or nil type and a should result in 0 when b is nil or false and 1 when b is true.
In Lua, these are selection operators, with short-circuit evaluation.
false and nil are "falsey"; Any other value is "truthy." Except for "falsey", the operand types don't matter and the resulting type isn't necessarily "boolean".
or selects (returns) the first truthy operand.
and selects the first operand if it is falsey, otherwise the second operand. It has a higher precedence than or.
This leads to several idioms:
b or 0 -- default to 0
t = t or {} -- existing or new, empty table
b and 1 or 0 -- coerce to 1, defaulting to 0
The difference between your two examples, is the second coerces to 1, while the first lets a "truthy" b be.
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