lua-users home
lua-l archive

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

Tables that can handle 'embedded' nils - it probably requires too much
change to the table library. Another possibility would be to have a
special unique non-nil value (call it 'null') which is used to
represent any embedded nils in {...}. Then whenever next() sees
'null', it returns a value of nil.  Of course, it might be useful to
mark such tables for efficiency reasons, and certainly {...} is not
the only place where 'null' could be useful, but it's the most

steve d.

On 10/27/07, Duck <> wrote:
> I know this is a regularly visited topic, so I am sure this suggestion
> isn't new. But here we go.
> You can't have nils in tables. Well, you can (since any uninitialised
> field comes out as 'nil' by default) and you can't (since writing nil into
> an existing field is formally given as the way to delete that field; PiL2,
> p.15).
> This is seen as a particular problem for vararg functions, since ...
> (the list of varargs passed in) can legitimately and importantly include
> nils which need to be accounted for explicitly. But {...} (the array of
> varargs passed in) can't deal with this, since nil fields and missing
> fields cannot be distinguished.
> So, code which might gracefully and efficiently use {...} must fall back
> ungracefully and less inefficiently (say the detractors) on select(), or
> table.maxn(), to deal correctly with varargs.
> But what if the __mode metakey of a table were extended to allow tables to
> support strong or weak nils, as well as strong or weak keys and values? By
> default, nils in tables would be weak, as they are now.  But if the __mode
> metakey contained "n", the table would have strong nils. 'Weak nils' mean
> that nil is an implicit default value for uninitialised fields; 'strong
> nils' mean that nil can explicitly be used as the value of any key in the
> table.
> Tables with strong nils would require all fields to be initialised
> explictly, with nil an allowed value. Assigning nil to a field would not
> delete it, but would simply set its value to nil. Accessing an
> uninitialised field woud raise an error by default, instead of returning
> an implicit nil. An explicit library call (e.g. table.remove() extended to
> allow a field name, not just an index numer, as its second argument) would
> be used to delete a field-value pair from a strong-nilled table.
> Wouldn't this keep everyone happy?
> Changing the semantics of {...} to make it produce a strong table would
> surely please varargs users? Existing code using select('#',...) and
> table.maxn({...}) would still work. Those who wanted to keep backward
> compatibility would simply change the default __mode of the {...} table
> back to weak-nilled. But when you wanted an array in which #table would
> 'just work' despite the presence of nils, you could have one. (And you
> could use the __index metamethod to override the error()-raising side
> effects for some or all missing fields, of course.)
> If you just did nothing and ignored the feature, things would just to work
> as usual, as long as tables were weak-nilled by default.
> Discuss. (Please don't flame if this is an already-suggested and
> long-torn-apart bad idea :)