Alex Burr writes: > On Sun, Feb 27, 2005 at 03:36:42PM -0700, Luke Palmer wrote: > > But the biggest problem is that if the user overloads 'equal' on two > > objects, the hash should consider them equal. We could require that to > > overload 'equal', you also have to overload .hash so that you've given > > some thought to the thing. The worry I have is that people will do: > > > > method hash() { 0 } > > This is why I think a 'canonicalize' method is better than a .hash' > method: if canonicalize is defined correctly, then .equal is just > {$a.canon() is_bitwise_identical_to $b.canon()}, so people don't have > to supply both.
Sure. And you know what's better than all of that? Transitive ordering on all objects, so that .equal is just: !($a < $b && $b < $a) But the reason we're not going with that is because it's very hard (both from a user perspective and computationally) to do that in the general case. And the same is true for canonicalization. Sure, when you have certain kinds of objects in mind, like strings, or trees, it's very easy to canonicalize. But when you have other objects in mind, like filehandles, graphs, or references to remote objects, it's hard or impossible to canonicalize. And in fact, there are some objects for which it's hard or impossible to define an .equal method. And those objects can't be hashed, plain and simple. If you need to hash them, you can define a type of hash that uses =:= as comparison, so that things are only equal if they are referentially equal. But I expect that we have can have a standard role that defines .hash and .equal in terms of .canonicalize, if it exists. We can also have a magical role that defines .canonicalize when it can. If .hash isn't defined when an object is used as a key of a hash (but .equal is), it will have to bite the speed bullet and use 0, probably along with a warning. Luke