lua-users home
lua-l archive

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

Some time ago, I had a discussion with a friend about what it would take to implement this in Lua. One of our concerns was to maintain compatibility with previous versions.

The core of the idea was that the number of indices in a multi-index table lookup would be decided during compilation. So, for example, t[f()] would always adjust the returns of f() to a single index. In the same way, t[f(), g()] would always be a 2-index access. There is precedent for this behavior for commas in Lua in loops like "for i = a,b,c". These do not work if you replace "a, b, c" with f(), even if f() returns "a, b, c". Since t[f()] would remain a 1-index access, regardless of the number of values returned by f(), and since t[f(), g()] is a syntax error today, I *think* there would be no compatibility problems. Compatibility aside, I think this would lead to fewer bugs anyway.

Access would be via __index and __newindex like today. These metamethods would receive all indices, instead of just the first. Below is what the "default" implementations would look like.

__index = function(t, i, ...)
    assert(select('#', ...) == 0, "too many indices")
    return rawget(t, i)

__newindex = function(t, i, v, ...)
    assert(select('#', ...) == 0, "too many indices")
    rawset(t, i, v)

Here it is obvious that maintaining compatibility is a bit awkward: In an ideal world, __newindex would receive the value before all indices. But since it receives the value after the index today, this change would break all existing code out there.

The behavior for __index and __newindex is preserved when the requested 1-index entry already exists in the table. The difference is that a multi-index entry is always assumed to be missing (so __newindex and __index are always called for multi-index accesses).

At any rate, user-defined __index and __newindex can do whatever they want with '...'.  If t is a userdata, it becomes trivial to perform multi-index accesses without taxing the garbage collector. If t is a Lua table, it becomes possible to linearize the multi-index to a single index and implement a matrix with a single table, without even using a proxy table.

Anyway, just my 2c.