lua-users home
lua-l archive

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


On Thu, Dec 30, 2010 at 12:56 AM, Dirk Laurie <dpl@sun.ac.za> wrote:
> All the trouble people have with the table length function and
> the table library, well over 100 posts by now, come down to one
> thing, and one thing only:
>
>    The functions designed for use on tables without holes
>    don't actually give an error message when applied to
>    tables with holes.

I disagree with this assessment.  In Lua, nil isn't truly a
first-class object, because it can't be stored in tables at all,
either as a key or a value.  The real problem, as I see it, is the
widespread refusal to accept this fact.

Now if you're only going to have a single data structure type in a
language, associative arrays are an excellent choice: they have nice
performance characteristics and are a powerful building block.  One
very useful set of keys are the positive integers, and Lua
acknowledges this with convenient syntax and optimized handling of
that use case.  But a table being used as an array is still a table
and still can't store nil.

The length operator's definition is nifty: no matter how tables are
implemented, the length can be efficiently calculated with an
unbounded binary search.  If you're using a table as an array, the
"length" matches your intuition.  If you're not, it doesn't, but don't
do that.

There have been complaints in these threads about the result of the
length operator not being deterministic -- that the same Lua code can
return different answers on different implementations -- but this is a
red herring.  The length operator could easily be made deterministic
by specifying precisely how the unbounded binary search must be
performed.  Then the answer would no longer be nondeterministic, but
it would still be *arbitrary*.  It still wouldn't be very useful for
non-array tables, and all of the complaints in these threads would
continue.

Lorenzo Donati got it exactly right -- if you want an
array-with-holes, build one out of tables and metamethods, just as you
would if you wanted a queue or a multiset or classes.  He's also right
that if there were a well-accepted common implementation of this, you
could point people to it and end these threads quickly.  What doesn't
feel wise to me is the plan of expanding the size of every table, and
increasing the performance cost of every table modification, just to
make # do something less confusing when you're using it on a non-array
table.

Or you could try to make nil first-class, but that's a broad change
with major and sweeping implications.  The end result would look like
quite a different language than what we have today!

Greg F