When using the Common Lisp sxhash
function on structs I'm getting the same value for all structs (in SBCL only structs of the same type). For instance, the following code prints two lists of integers all of which have the same value.
(progn
(defstruct foo
data)
(print (mapcar #'sxhash (loop for i below 10 collect (make-foo :data i))))
(defstruct bar
data)
(print (mapcar #'sxhash (loop for i below 10 collect (make-bar :data i)))))
;;; Allegro
(319 319 319 319 319 319 319 319 319 319)
(319 319 319 319 319 319 319 319 319 319)
;;; SBCL
(22591133455133788 22591133455133788 22591133455133788 22591133455133788
22591133455133788 22591133455133788 22591133455133788 22591133455133788
22591133455133788 22591133455133788)
(21321591953876048 21321591953876048 21321591953876048 21321591953876048
21321591953876048 21321591953876048 21321591953876048 21321591953876048
21321591953876048 21321591953876048)
I've tried this in both Allegro Lisp and SBCL and they both return (different) constants for all structs (of same type in SBCL). On the linked sxhash
Hyperspec page there are the following statements:
For any two objects, x and y, both of which are bit vectors, characters, conses, numbers, pathnames, strings, or symbols, and which are similar, (sxhash x) and (sxhash y) yield the same mathematical value even if x and y exist in different Lisp images of the same implementation. See Section 3.2.4 (Literal Objects in Compiled Files).
The hash-code for an object is always the same within a single session provided that the object is not visibly modified with regard to the equivalence test equal. See Section 18.1.2 (Modifying Hash Table Keys).
The latter statement does not specify, but seems to imply, that it would be sensible that two structs which are not equal
will have differing hash codes (modulo collision). However, structs are suspiciously absent from the list in the first paragraph. At first I chalked this up to a bug in Allegro Lisp but now that I see it in two different implementations I think there must be something about the spec I don't understand.
(equal x y)
then(= (sxhash x) (sxhash y))
. I seem to recall (but I may be conflating comp.lang.lisp and the hyperspec) that what you are seeing is not uncommon, in that there are different things taht will have the samesxhash
hash value. – Panisxhash
to be the same for similar objects in the same implementation. Also, they can't do recursive traversal (safely) because the object may be mutated. – Slipshod