[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: value semantics and __hash metamethod (?)
- From: Renato Maia <maia@...>
- Date: Sun, 21 Nov 2010 09:12:33 -0200
On 20 Nov 2010, at 16:35, Lorenzo Donati wrote:
All this is a bit cumbersome, because for every new "value class"
you need a new specialized "container".
You can just replace 'vec_key.repr' by something like
'getmetatable(vec_key):__hash()'. For an example, take a look at:
http://sano.luaforge.net/documentation/HashMap.html
Therefore I'd find useful a metamethod which, if present on the item
being used as key, could be used to retrieve the actual key used for
hashing.
[snip]
But I realize that that maybe this check on every access for every
key could be a big performance hit.
Yes, besides the probable performance and complexity overhead in the
majority of uses of Lua tables where such thing is not needed, such
feature is only one possible solution for this problem of using
complex objects as a key of a map, not necessarily the best one. So
maybe it is better to let the programmer implement the best solution
himself (or use a third-party library) when necessary.
That's why I asked: I expected that someone could say I proposed
something silly, but being criticized constructively is a good way
to learn faster :-).
Have you searched the list archives for '__hash'?
I'm discovering day by day that I have to unlearn so much! :-)
I don't know what you mean by "unlearn", but it is always nice to
learn new ways of solving old problems. In your example, consider
using internalized tuples[1], for example:
local tuple = require "tuple"
local tuple_index = tuple.index -- faster than 'tuple.create'
local Vec_MT = {}
Vec_MT.__index = Vec_MT
-- memoize table to internalize 'vectors'
local tuple2vector = setmetatable({}, {
__mode = "v",
__index = function(self, tuple)
local x, y = tuple()
local vector = setmetatable({ x=x, y=y }, Vec_MT)
rawset(self, tuple, vector)
return vector
end,
})
-- very simple 2D vector object constructor
local function Vec(x, y)
return tuple2vector[ tuple_index[x][y] ]
end
function Vec_MT:__add(v)
return Vec(v.x + self.x, v.y + self.y)
end
-- let's exercise our "class"
local v1, v2, v3 = Vec(1,2), Vec(1,2), Vec(2,4)
assert( rawequal(v1, v2) )
assert( not rawequal(v1, v3) )
assert( v1 == v2 )
assert( v1 ~= v3 )
-- now we want to put Vec objects in a table as keys
local v_set = { [v1] = true, [v2] = true, [v3] = true }
assert(v_set[Vec(1,2)] == true)
assert(v_set[v1 + v2] == true)
assert(v_set[v1 + v3] == nil)
[1] http://www.tecgraf.puc-rio.br/~maia/lua/tuple/
--
Renato Maia
Computer Scientist
Tecgraf/PUC-Rio
__________________________
http://www.inf.puc-rio.br/~maia/