lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Jul 1, 2013, at 18:32, Philipp Janda <> wrote:

>> Under this proposal, nils are no longer holes.
> ... but holes are nils. Or stated differently: There are explicit nils,
> which are part of a table, and implicit (deleted or never assigned)
> nils, which are still holes. One question is: Should accessing explicit
> nils invoke __(new)index metamethods?
> I'd argue that if you want nils as part of tables, then go all the way,
> and remove nil as a default value. Throw an error when accessing a
> non-existing field instead. No need for strict.lua any more, yay! You
> could simulate the old behavior using a nil-returning __index metamethod.
> Anything in between seems messy, IMHO ...
>>> That could be useful, but also a bit confusing as it means a key set to nil
>>> and a key that was never set (or was deleted) are different things, but both
>>> have a nil value.
>> You can tell the difference with table.has().
> table.has() and table.delete() would be essential functions not limited
> to arrays, so they should go into the base library ...
>> /s/ Adam
> Philip

Here is where I should have picked up from...

I think if you define __index as defaulting to returning nil on
undefined values, then it is not messy, except for one glaring issue.

There would need to be a way to explain why all tables that don't have
metatables return nil when an accessed key is undefined.


All tables use a default metatable, if one is not defined. It has the
sole metamethod, which if defined in Lua would read:

_MT.__index = function(t, I) return nil end

To remove this functionality, assign a metatable and the. set its
__index metamethod to nil.

Imagine the following behavior:

print(foo) --> nil
setmetatable(_G, {__index = nil})

pcall(print, foo) --> false, "error: Attempt to access undefined value 'foo'."


print(foo) -->  nil --admitting that pcall is a bit confusing now...
false, nil? Or true, nil? The current behavior is explainable.

I think that an important point here is that there is no new type. You
cannot set something to undefined. It just is undefined or you make it
undefined with delete. Also, accessing something undefined should be
an error, I think. This would be a big change for locals, given that
there wouldn't be a "default metatable."

However, I think that it should be, as you say, consistent for the
whole language. Not just for tables.

So delete, exists/has and I'd throw out _MT with the aforementioned
__index function.

If I gave a single `empty` type 0 chance, then I give this #DIV0. :)

I do think that this would make things even more consistent within the language.

-Andrew Starks

"As we get older, and stop making sense"
-David Byrne