The == implementation for AStruct and default isequal did not fulfill this documented requirement: “isequal is the comparison function used by hash tables (Dict ). isequal(x,y) must imply that hash(x) == hash(y) .” As a consequence, unique is unable to put them in the same slot of a Set.
Thank you very much for this detailed explanation !
I wonder if some tooling could help developers by forcing them to implement a hash method for each custom isequal method (I have spent some energy trying to figure out the problem before this discourse post).
You are right, but one has to guess that he may not understand what is the semantic of isequal in order to look at the corresponding docstring.
The docstring of unique does not make any reference to the hash function:
help?> unique
search: unique unique! allunique
unique(itr)
Return an array containing only the unique elements of collection itr, as
determined by isequal, in the order that the first of each set of equivalent
elements originally appears. The element type of the input is preserved.
See also: unique!, allunique, allequal.
Right, I meant the ==/isequal/hash docstrings. It does seem strange to me that unique mentions isequal in particular when hash table types must use hash then isequal to do key equality properly.
Note that I think that I would have I consider the hash function if I was dealing with Dict. But since I was only using regular Arrays, I have (wrongly) assumed that unique implementation only implied a bunch of call to isequal.
Maybe the unique docstring could be improved, mentioning the hash function.