5.6.1 Value Types

In the case of a pure value, all you need to do is to tell FSet which of its slots define its value. This is usually all of them, but in some cases you may have “metadata” slots that carry information associated with the value, but are not part of that value. FSet provides a convenient macro for supplying this information:

Macro: define-equality-slots class &rest slots/accessors

A handy macro for specifying which slots of the class determine whether instances are equal. Generates methods on compare and hash-value. These methods call each of slots/accessors on the object(s); the results are recursively compared or hashed, using compare or hash-value respectively. Comparison uses the slots or accessors in the order provided.

For best performance (at least on SBCL), it is recommended to supply slot names as symbols for standard classes — these will turn into slot-value forms — but accessor names as functions for structure classes. Arbitrary functions on the class may also be supplied.

(A deprecated feature, mentioned for completeness: if the symbol :eql is supplied as the last accessor, then if the comparisons by the other supplied accessors all return :equal but the arguments are not eql, the generated compare method returns :unequal.)

Examples:

(defstruct point x y)
(define-equality-slots point #'x #'y)

(defclass part () ((part-number ...) ...))
(define-equality-slots part 'part-number)

If you’re using define-class to define your value type, there’s another way: just include :equality in the slot options for each equality slot.