Here is a plan for fixing Lua's problem with nil being used for false (which is not explained anywhere on this site yet, refer to lua-l). It still needs more work.
Add a new type "false" that has a single value of
false. (This is similar to how type "nil" has a single value
nil, and follows Scheme.) Examples:
print(type(false)) --> "false"
Relational operators return
false for false and a value other than
nil for true. Examples:
5 > 6 --> false 5 ~= false --> "true" nil == false --> false
Logical operators consider values other than
nil as true. If the result of a logical operator is
nil (due to conjunction/disjunction with nil) it will be converted to
false. In other words the result of both relational and logical operators will never be
nil and 5 --> false nil or 5 --> 5 5 and false --> false 5 or false --> 5 not 5 --> false
The bad news... here are some examples of what would get broken. However none seem like sane programming patterns.
if (a>b) == nil then ... end -- testing boolean expression against nil var3 = var1 or var2 -- expecting possible nil var3 var3 = var1 and var2 -- "
The good news... this change allows programs to distinguish between a variable assigned from a boolean expression and a non-existing variable. For example:
-- try one of these --IsOk = nil --IsOk = SomePredicateFunction() --IsOk = "I don't know" -- new style test for non-existance if IsOk == nil then ... end -- new style test for existance if IsOk ~= nil then ... end -- new style test for true/false (assuming value is not nil) -- also: old style test for existance (assuming value is not false, -- which holds for legacy code) if IsOk then ... end
I made a patch for Lua 4.0 to implement a boolean type. It does not behave exactly as written above -- the operators
or are different. In Lua they are not strict boolean operators; they may give non-boolean results and will not evaluate their second operand if the outcome of expression is known by the first operand. So I defined them like this:
and(a,b): if a==nil or a==false then return a else return b end or(a,b): if a~=nil and a~=false then return a else return b end
where b is only evaluated when required. With this definition regularly used Lua constructs with these operators behave as before. I.e. your example above (
var3 = var1 and/or var2) may give a nil to var3.
Everything else is as described as above: all comparison operators and the
not operator return either false (a reserved keyword now) or the number 1 as true. The conditional statements (if/while/repeat) and
not assume everything except
false as true. There are 3 new API functions: lua_pushfalse, lua_isfalse, and lua_istrue (not nil nor false). The new tag is named LUA_TFALSE and the type string is "false".
if x==nil" is no longer the same as "
if not x" as is "
if x~=nil" no longer the same as "
if x". Better check your programs...
Ah, and the patch is here: Files:wiki_insecure/users/froese/bool-patch-1
Great! One minor complaint about the patch... when adding new defines (
LUA_TFALSE) there is no reason to change existing defines. Likewise for new opcodes. This reduces conflict with other patches. --JohnBelmonte
Maybe this should be rounded out by adding a global
true set to 1.