Speaking of which, how do we ensure the immutability of keys being put into the hash? I think Perl copied the string, so that:
$b = "aa"; $a{$b} = 1; chop $b; print $a{"aa"}; still works. If we start storing full thingies into the keys of a hash, we either need to make deep copies of these, or copy enough to ensure the hashing function has all that it needs. Say we do: $b = new Cat(); $a{$b} = 1; $b->somefunctionthatchangesthehashvalue(); $a{$b} doesn't find anything, since $b was hashed under it's old identity. Also, Perl allowed this before: $b = "aa"; %a{$b} = 1; print $a{"aa"}; Will it allow this? $b = new Cat(); %a{$b} = 1; print $a{new Cat()}; If it does, how does it determine equality of two objects? What if Cat includes a counter that determines which number it is in some total ordering of cats. Will the above still work? Java had all sorts of problems where they force immutability of an object onto the user of their Collection API. It's a pain in the ass, and the source of stupid bugs, where your object changes it's hash value without being rehashed. How will perl handle this? If it automatically rehashed objects in whatever tables they are stored in (forget the speed hit for now), then we still have the problem of: $a = "a"; %c{$a} = 1; $b = "aa"; %c{$b} = 2; chop $b; print %c{"a"}; #what gets printed? According to perl 5 semantics, this would print 1. But according to the rehashing rule above, this is ambiguous. So that's not an option. I personally liked the stringification of keys. It made things a LOT simpler. :) Finally, one last option is to hash based on some memory address, so that when we store objects in there, we can be assured of no two of them pointing to the same place, or worrying about the hash function changing. Assuming we work around our copying GC some way to get a unique object identity value, we still have the problem of two equivalent strings hashing to different places, or two equivalent arrays hashing to different values. I can make a case for the latter being a good thing, but not the former, as it breaks perl5 semantics. Two options I see are: a) stringify everything, and make life simpler. I never really had a problem with stringified keys... b) strings get hashed like perl5. everything else gets hashed based on some unique object identifier (memory address) that's constant throughout the life of the object. This means that in order for an object to be able to have equality work in hashtables, from two objects constructed at different points in time, they'd need to overload the operator:hash() function to return a string. Or has this matter been thought through already? Thanks, Mike Lambert Aaron Sherman wrote: > Date: 16 Apr 2002 12:13:55 -0400 > From: Aaron Sherman <[EMAIL PROTECTED]> > To: Perl6 Language List <[EMAIL PROTECTED]> > Subject: Hashes, Stringification, Hashing and Strings > > In this example: > > %hash = ($a=>$b); > > $a can be anything. In fact, since Perl6 promises to retain the original > value of $a, we're rather encouraged to store complex data there. But, > this poses a problem. The key to use for hashing might not ideally be > the string representation. > > For example, if I'm hashing a collection of special file objects, it > might be useful in one context to do: > > method operator:qq () { > return read_whole_file(); > } > > But, if I have 100 of these objects, and I try to put them in a hash, > life could get ugly fast! > > More helpful would be to have this builtin: > > method operator:hash () { > return operator:qq(); > } > > and then allow me to override it in my class like so: > > method operator:hash () { > return filename(); > } > > This allows me to specify separate hashing and stringification methods, > but retains Perl's original default of combining the two. > > >