Denis, That can be done with an canEqual implementation as described by http://www.artima.com/lejava/articles/equality.html. For this reason, itâs better to multiply successive fields by a constant
(e.g. shifting left by 2) before XORing them into the hash. But then, for objects with lots of fields, the later ones are lot completely, because they are multiplied by a number so large that they are out of the range of the hash.
I think this exactly what HasCodeBuidler does, however I saw no special treatment for hashes made of many fields.... On Mon, Oct 2, 2017 at 12:38 PM, Prof. Andrew P. Black <black@cs.pdx.edu> wrote:
On 2 Oct 2017, at 16:37 , Sean P. DeNigris <sean@clipperadams.com> wrote:
2. #hash ^ var1 hash bitXor: (var2 hash bitXor: var3 hash) Is this implementation always safe? It's what I usually hand roll based on what I've seen, but Andres Valloud wrote a whole (large) book on hashing, so I've always wondered if I was missing somethingâ¦
If you read Andres book (which is hard, because he wonât make it available online), you will learn that itâs better to take the order of the instance variables into account. #bitXor: is commutative, so it of course ignores order.
In other words, if you have a Point with x and y fields, then 3@9 and 9@3 will have the same hash.
For this reason, itâs better to multiply successive fields by a constant (e.g. shifting left by 2) before XORing them into the hash. But then, for objects with lots of fields, the later ones are lot completely, because they are multiplied by a number so large that they are out of the range of the hash.
One can avoid this by using a circular shift to implement the multiply.
All of this was, I thought, implemented in a #hashCombine: method, but I canât find it in my image. Maybe some other Smalltalk ...