lua-users home
lua-l archive

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


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