Re:How Many Lines of C It Takes to Execute a and B in Python?
by tialaramex on Monday December 11, 2023 @09:24AM
(#38600878)
Rust is doing something even more subtle here than just making the hash function a container property. There are two inter-related Rust traits, Hash is a trait which types implement to explain abstractly how to hash that type, but it's written in terms of a Hasher trait so you can drop in a different function with the same API. The Rust standard library provides a derive macro for Hash, so most people can just gesture vaguely at their custom type and have it hashed correctly for any hash functions they need. The naïve approach here easily ends up doing a bad job either colliding hashes for correlated objects in a surprising way or emitting different hashes for equivalent objects because people who make a user defined type probably aren't hashing experts.
[ Parent
| on HN ]
Re:How Many Lines of C It Takes to Execute a and B in Python?
by masklinn on Monday December 11, 2023 @10:48AM
(#38601619)
We can get into the weeds about the details, but what I'm talking about is mostly that in Python (and in most languages really, AFAIK Ruby, Java, or C# are the same to list just a few) objects have to return the hash itself, so the hash function is fixed by the type.
In Rust, the Hash trait is only used to feed data to a hasher such that the type can decide what should be hashed. The creation of the hasher is done by the collection, and thus provides better opportunities / flexibility in customising the hash function.
Re:How Many Lines of C It Takes to Execute a and B in Python?
by tialaramex on Monday December 11, 2023 @11:30AM
(#38602013)
The derive macro is also key here. Have you ever looked at the machinery needed for Java's URI type to have a halfway useful hashCode implementation? It's pretty elaborate, there's just no way the average programmer will do that work correctly for their own types even ignoring the desire to allow different hash functions. Rust programmers are almost always able to just write #[derive(Hash)] and not worry about it.