Closed AstraLuma closed 3 years ago
@astronouth7303 We discussed in a previous PR that the current API for Vector
cannot implement the hash
protocol because hash(vector) == hash(vector_like)
would need to hold whenever vector == vector_like
.
It might be possible to work our way around that, if (and only if) tuple
is the only VectorLike
type that is hashable; if so, we “just” need to guarantee that hash(v) == hash((v.x, v.y))
.
Update: this is not the case, frozendict({"x": 0, "y": 1})
is also an hashable vector-like, with an incompatible hash.
This is the point where I wish python had "semantically equal" or "equal enough" vs "exactly equal".
For cases where users would want ==
, we'd want "semantically equal" (that is, they carry the same abstract vector idea, even if the specific data structures differ).
For dictionaries and uses involving hash()
, we'd want "exactly equal", where "this is the same value", right?
Practically, you'd expect immutable values to be usable as dictionary keys. But for us, that's a can of worms.
I mean, I'd find it very surprising for a tuple(0, 1) to hash to the same thing as Vector(0, 1) but that might just be experience with Python and not genuinely reasonable logic.
Properly implementing __hash__()
from scratch is surprisingly tricky, so a quick (and probably not unreasonable) implementation would be hash((x, y))
, or just use the hash of the tuple.
Doing something like hash(('Vector', x, y))
might work? but there's the bigger problem that "Do vector-likes count for dictionary keys?"
@pathunstrom The protocol for hash()
specifies that property must hold. I wrote tests that show we can't currently comply with that protocol.
Also, it would be very surprising to have t[x] != t[y]
when x == y
(if t
is any sort of container that uses hashes), and violating the hash
invariant might even cause the container to throw an exception or fail in worse ways (uncatchable assertion failure from C, segfault, ...)
so a quick (and probably not unreasonable) implementation would be hash((x, y))
@astronouth7303 dataclass
' automatic hash implementation is seemingly equivalent to that, it's not the actual problem.
Closing, as this is impossible to do in a spec-compliant way.
Allow
Vector
to be used as dictionary keys.While I don't expect to do much indexing by
Vector
, this is useful if you want to map Vector -> value for some reason (eg, in ppb-oneko, mapping directional vectors to their animation).