But then the issue of sparse arrays and table.insert() and table.remove()
come into play. Follow along here ... I do:
t = { [15] = "first" }
Right now, in standard Lua, #t==0. With my thought experiment, #t=15. Next
table.insert(t,"second")
still works, because now the table is { [15] = "first" , [16] = "second" }
and all is fine, until
table.insert(t,1,"Ha ha! I cut in line!")
Items 15 and 16 are stored in the hash portion, not the array portion. Item
1 is (possibly?) stored in the array portion. Should we go through and
renumber 15 and 16 to 16 and 17? Or not? The same issue with
table.remove():
table.remove(t,13)-- remove the unlucky member
So it was a nice idea, but an utter failure in the actual world.
First off, don’t mix in the “hash part vs array part” stuff. The purely internal use of a C language array to store some of the integer keys is just internal plumbing and not related to logical Lua “arrays” (strictly, sequences). Remember a valid sequence might be stored all in the hash part, all in the array part, or partly in both (and this may change during the life of the table).
As I said, there are lots of semantic details to sort out, and table.insert() + table.remove() are part of that. One approach is that for a table of length N, table.insert() at indices from 1 to N+1 increases the length of the array (note it's N+1, so append extends the array), and table.remove() at indices from 1 to N decreases the length of the array. An alternate is that they do nothing to the length at all; they are, after all, named “table.insert()” not “array.insert()”.
An explicit length is really taking the “.n” idea and making it first-class, so that functions like table.insert() can be “length aware”, and both the C API and Lua API agree on a standard definitive way to manage array lengths.
—Tim