lua-users home
lua-l archive

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


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.


And yes, a given __key *should* return the same value each time it is
called for a given userdata in a given state. But if it doesn’t strange
things happen. Strange in that they vastly complicate the table contract.
And to what end?

I’m not being obtuse here, I just don’t see the bang for the buck.

   As I present these examples, I'm just not seeing it either, given that a
module that wants the behavior of '__key' can just return interned values.

Wrong examples ;-)

You want `t[bigint(3)] = x` to be equivalent to `t[3] = x`, but `bigint(3)+bigint(3)` should use custom big integer addition, *not* the built-in Lua integer addition. For `bigint("2^128")` you'll still use an interned userdata so that `t[bigint("2^128")] = 1; print(t[bigint("2^128")])` works as expected (`__key()` would just return the userdata itself in this case).

Another example would be a UTF8String where `#` returns the number of characters not bytes, but which behaves like a regular string when used as a key in a table (and preferably when compared to a regular string via `==`, but that's a different story).


   -spc (__key is hard!  Let's make rockets!)


It's not hard: Use the result of `getmetatable(x):__key()` instead of `x` itself when doing `t[x]` or `t[x] = y`. But it's only useful under very specific circumstances (i.e. for implementing custom number or string types).


Philipp