|
Am 18.07.2016 um 03:47 schröbte Tim Hill:
On Jul 17, 2016, at 5:14 AM, Philipp Janda <siffiejoe@gmx.net> wrote: Am 17.07.2016 um 10:05 schröbte Sean Conner:It was thus said that the Great Tim Hill once stated:Where is the synthetic key value stored then? It must be stored in the key+value slot of the table. Where is the userdata stored? In the same place. So now we are storing three items per table slot, not two. Seems to me a significant impact.The synthetic key is stored as key in the table (or is implicit in the array part). The userdata is not stored at all (unless `__key()` returns it). The synthetic key is used _instead of_ the original userdata.Which is pretty horrible too… u = <some userdata with __key> t = {} t[u] = “foo” — Lua calls __key here t[u] = “bar" — Let’s hope __key returns same value every time!
That's the point. Its purpose is to return the canonical representative of the equivalence class that also contains `u`.
u = nil — Goodbye last reference to u! So now we have the potential for a userdata to splatter content all over a table by playing tricks with __key. Not good. And a userdata that vanishes even though we have (apparently) stored it as a table key. Not good.
`__key()` is only useful for value types (specifically number and string types). It doesn't matter if the current userdata vanishes. When you want to do some indexing, you simply create a new (but equivalent) userdata.
And if u doesnt return the same key every time, good luck finding the key in the table, short of enumerating the whole thing.
If you don't index with an equivalent key, you won't get the corresponding value out of the table and it stays there untouched until the table is garbage-collected. Nothing new here. Besides, since `u` has value type, I can't see a reason why the result of `__key()` should change during the lifetime of `u`. Also there are other, existing metamethods that should consistently return the same value, e.g. `__lt` with `table.sort()`.
The point is really this: __key modifies the contract for a table dramatically.
What exactly is the contract for a table? Taking metamethods into account there is not much we can say for sure about the behavior of a table ...
It can’t just drop transparently into existing code without the danger of breaking something.
It doesn't need to (although I think it could in many cases). It would be a new feature, and so it only has to work with new code.
I don't think `__key` is particularly useful, but I doubt that it would cause much problems.
—Tim
Philipp