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

Reply via email to