Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Vector hashable #174

Closed
AstraLuma opened this issue Jun 13, 2019 · 8 comments
Closed

Make Vector hashable #174

AstraLuma opened this issue Jun 13, 2019 · 8 comments

Comments

@AstraLuma
Copy link
Member

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).

@nbraud
Copy link
Collaborator

nbraud commented Jun 27, 2019

@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)).

@nbraud
Copy link
Collaborator

nbraud commented Jun 27, 2019

Update: this is not the case, frozendict({"x": 0, "y": 1}) is also an hashable vector-like, with an incompatible hash.

@AstraLuma
Copy link
Member Author

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.

@pathunstrom
Copy link
Collaborator

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.

@AstraLuma
Copy link
Member Author

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?"

@nbraud
Copy link
Collaborator

nbraud commented Jun 29, 2019

@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, ...)

@nbraud
Copy link
Collaborator

nbraud commented Jun 29, 2019

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.

@nbraud
Copy link
Collaborator

nbraud commented Oct 23, 2021

Closing, as this is impossible to do in a spec-compliant way.

@nbraud nbraud closed this as completed Oct 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants