|
We havet(i1, i2, ...) --> getmetatable(t).__call(t, i1, i2, ...)This is always called.We are considering something liket[i1, i2, ...] --> getmetatable(t).__index(t, i1, i2, ...)t[i1, i2, ...] = v --> getmetatable(t).__newindex(t, v, i1, i2, ...)They would be incompatible both because of the t[f()] issue, because the parameter order in __newindex(t, i1, v, i2, ...) is awkward, and because these methods are only called when the table index doesn't exist.t[f()] I don't quite understand why it would be an issue at all; as I described earlier, if the default handler just ignores the extra indices it's fine.
The parameter order is awkward, but that's not actually an incompatibility.
I do see the potential issue with the way the methods are called. With my suggested behavior, it only comes up if you have mixed assignments to t[i] and t[i,j] on the same table and the __newindex isn't built to deal with it. I sort of feel like that's a case of "well, then don't do that" -- if you're intending your table to support multi-indexed data, then you shouldn't ever assign data to a publicly-accessible first index, and the failure mode would simply be considered a bug in the code.
Should we instead maket(i1, i2, ...) = v --> getmetatable(t).__lvaluecall(t, v, i1, i2, ...) ?This solves the l-value problem with the notation, makes the meaning of t(f()) = v completely obvious, and would always call the metamethod, just like t() currently does.Since there are no breaking changes involved, anyone would be free to design a multi-index translation scheme and there even could be a predefined implementation as you suggest.Now, to be fair, independent of multidimensional indexing, this would be a pretty nice thing to have anyway, especially for DSLs. (Though I'd consider __assigncall instead of __lvaluecall unless you have other places I'm not thinking of where Lua has lvalues.)
Now if somebody finds a way for __lvaluecall to receive multiple *values* along with multiple indices, we could even have tables that store and return multi-dimensional data.Not sure how to work this out, but it sure would be cool.At that point you might as well just promote tuples to a first-class object instead of juggling them implicitly with the varargs syntax. That would solve ALL of the problems.