Boolean Type Proposal |
|
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 false
/nil
for true. Examples:
5 > 6 --> false 5 ~= false --> "true" nil == false --> false
Logical operators consider values other than false
/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
. Examples:
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 and
and 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 nil
and 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".
Some warnings:
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
-- EdgarToernig?
Great! One minor complaint about the patch... when adding new defines (LUA_REFFALSE
, 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.