5.6.2 Reference Types

For a mutable reference type, I strongly recommend that you distinguish instances by identity rather than by content. FSet provides two convenient ways to do this, depending on whether your class is a standard class (defined by defclass) or a structure class (defstruct). For a standard class, all you have to do is to include identity-equality-mixin as a superclass; FSet handles the rest.

For a structure class, you can similarly specify identity-equality-struct to the :include option in the defstruct form:

(defstruct (frob
	     (:include identity-equality-struct))
  size
  color
  location)

Since structure classes support only single inheritance, if you have a tree of such classes related by inheritance, this inclusion will have to be placed on the root class of the tree. If that’s not possible for some reason — perhaps the root class is in another codebase, which you can’t alter — there is another way. You can add an explicit id slot and supply that to define-equality-slots. For convenience in doing this, FSet exports define-atomic-series and increment-atomic-series. Here’s an example:

(define-atomic-series next-frob-id)

(defstruct (frob
	     (:constructor make-frob (size color location
				      &aux (id (increment-atomic-series next-frob-id)))))
  id
  color
  location)

(define-equality-slots frob #'frob-id)

Every time make-frob is called, the id of the result will be initialized to the next integer in the series.