lua-users home
lua-l archive

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

We have
t(i1, i2, ...) --> getmetatable(t).__call(t, i1, i2, ...)
This is always called.

We are considering something like
t[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 agree. It is only an incompatibility if the default behavior is to do something with those extra indices. Having some kind of default behavior for the extra indices is one of the options being discussed here. In that case, I think we would have such a big incompatibility that we might as well change the parameter order so it is not awkward. :)

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.

I don't feel strongly about this. But the asymmetry in the behavior is unfortunate. We end up back in the default behavior. It would be nice if the native table implementation knew about multiple indices. Maybe someone can come up with an implementation that is just as good as the current one is for single indices but that also works very well for multiple indices. Then the __index and __newindex would only be invoked for missing multi-index combinations.

But then the default behavior would be triggered by something like t[f()], bringing the incompatibility back. If the number of indices was defined syntactically, rather than at run time, there would be no incompatibility.

Should we instead make
t(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.)

Your name is better.

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.

Except for Roberto's. :)