4 ms·
> The one key difference is that any object can be a key in a Lua table How does this work? Internally it is implemented using a hashmap so somehow they must g
by pkaye 8y ago
> The one key difference is that any object can be a key in a Lua table
How does this work? Internally it is implemented using a hashmap so somehow they must generate a hash value of the object? What if the object has member variables that are themselves objects? What if those things point to each other in a cycle?
- nikki93 8y agoEquivalence is by whether that name refers to the same object (like “pointers” in C).
- masklinn 8y agoIn that case the object's is hashed by identity (location in memory). That's how Javascript's Map (separate from a bare object) works for instance: > let m = new Map > let o = {} > m.set({}, 1) Map { {} => 1 } > m.set(o, 2) Map { {} => 1, {} => 2 } > m.get({}) undefined > m.get(o) 2 or Python's dicts: >>> class A: pass ... >>> a1 = A() >>> a2 = A() >>> {a1: 1, a2: 2, A(): 3} >>> d = {a1: 1, a2: 2, A(): 3} >>> d {<__main__.A object at 0x107a9f1d0>: 1, <__main__.A object at 0x107a9f208>: 2, <__main__.A object at 0x107a9f2b0>: 3} >>> d[A()] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: <__main__.A object at 0x107a9f240> >>> d[a1] 1 >>> d[a2] 2 or Ruby's: > class A; end > a1 = A.new > a2 = A.new > m = { a1 => 1, a2 => 2, A.new => 3} => {#<A:0x007fbe691ecdf8>=>1, #<A:0x007fbe691f4f08>=>2, #<A:0x007fbe6920efc0>=>3} > m[A.new] => nil > m[a1] => 1 > m[a2] => 2 Statically typed languages can more easily constrain keys[0], but even then the lure of all objects being hashable and equatable is strong e.g. I'm pretty sure all Java and C# objects are hashable and equatable (and can be used as hashmap keys out of the box). [0] Rust's hashmap requires that its keys implement Hash and Eq, neither of which are implemented by default; Haskell's Data.Map that its key be Ord; ...