Skip to content

Instantly share code, notes, and snippets.

@gilzoide
Last active December 16, 2023 12:33
Show Gist options
  • Save gilzoide/6d7c435e4585f8ba96592f89f2442845 to your computer and use it in GitHub Desktop.
Save gilzoide/6d7c435e4585f8ba96592f89f2442845 to your computer and use it in GitHub Desktop.
Logical XOR in lua
-- Returns false if value is falsey (`nil` or `false`), returns true if value is truthy (everything else)
function toboolean(v)
return v ~= nil and v ~= false
end
-- Returns true if one value is falsey and the other is truthy, returns false otherwise
function xor(a, b)
return toboolean(a) ~= toboolean(b)
end
@KevinTyrrell
Copy link

Oops, wrote false instead of true above, fixed now. Also don't know why I thought nesting the not outside was necessary as just inverting the equality is equivalent.

Unfortunately both the above and the not approach fail on 0 and 1 since Lua considers both 'truthy' values. Anything outside of nil and false are truthy and therefor not 0 evaluates to false. For anyone finding this gist on search engines like I did, for numbers use bit.bxor instead from the standard library.

@gilzoide
Copy link
Author

Unfortunately both the above and the not approach fail on 0 and 1 since Lua considers both 'truthy' values.

That's not failing, this is just how Lua behaves. I labeled this gist "logical xor" because it follows Lua's boolean logic, which is exactly what I needed at the time.

But it's easy enough to patch toboolean and have a version of xor that considers 0 as false, if anybody ever needs it:

function toboolean(v)
    return v ~= nil and v ~= false and v ~= 0
end

function xor(a, b)
    return toboolean(a) ~= toboolean(b)
end

It's also easy enough to inline the toboolean operation into xor as well, although I'd say that's a microoptimization and won't matter in most use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment