lua-users home
lua-l archive

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



On Oct 2, 2013, at 6:51 AM, Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> wrote:

It's too bad that the tone was over the top and unnecessarily disrespectful.

I'm sure Tim meant no offense. None was taken by me.

The # operator for tables remain a source of confusion for users.
I wish it was different but there it is.


I'm glad you didn't take offense, none was intended.

So I'd like to take a moment to float something (see, I'm not *just* a citric). Consider the Lua definition of sequence (from the 5.3 reference manual):

"We use the term sequence to denote a table where the set of all positive numeric keys is equal to {1..n} for some integer n, which is called the length of the sequence."

Now let's amend this very slightly:

"We use the term sequence to denote a table where, at all times for the life of the table, the set of all positive numeric keys is equal to {1..n} for some integer n, which is called the length of the sequence."

This is of course a stricter definition, since it means that a sequence must be constructed in ascending order (it doesn't prevent you from constructing a table out of order, it just means such a table is not a sequence from the above definition). It also means a table with no numeric keys at all *is* a sequence, if you allow the set of positive numeric keys to be empty.

We now define # as: "The # operator returns the length of a sequence, or nil if the table does not contain a sequence." This makes # completely predictable, and avoids any confusion over "tables with holes". It also makes # the *test* for a sequence ("if #t then … end").

Is this hard to implement? I think not. Essentially each new empty table starts off life as a sequence (with # returning 0). As each element is added, it is trivial to check for the "sequence-ness" of the table:

if type(new_key) == "number") and bSequence then
bSequence = (new_key == #t +1)
end

(I'm assuming bSequence is some hidden per-table state inside the table implementation code in Lua, and that the above pseudo-code is really C code inside Lua.)

This is (imho) less of a change to #'s behavior than might at first appear. It's easy to construct odd tables that LOOK like valid sequences but give strange results with # .. in my model # doesn't give odd results, it gives nil. Essentially # is more strict.

Pros:
-- # is easier to understand, and far more predictable
-- There is a language-defined way to test for a sequence
-- Very little performance loss; the logic change is minimal and does not perturb the existing table internal structure

Cons:
-- It's a language change (and a change to #, though you could expose the sequence flag elsewhere, such as an API).
-- It's slightly odd that once a table loses its sequence-ness its gone for good (even if it's emptied of all keys).
-- The most common question will be "I constructed my array in XXX order, and # returns nil .. why?"

--Tim