anchor.diff:      :initform nil)))
   
   (defmethod closer-mop:finalize-inheritance :after ((class data-class))
  -  (let ((slot-names (mapcar 'closer-mop:slot-definition-name
  -                            (closer-mop:class-slots class))))
  -    (eval
  -     `(defmethod clone ((object ,(class-name class)))
  -          (clone-slots ,slot-names
  -           object
  -           (make-instance ',(class-name class)))))
  -
  -    (eval
  -     `(defmethod fset:compare ((first ,(class-name class)) (second ,(class-name class)))
  -          (let ((result (fset:compare-slots
  -                         first second
  -                         ,@(mapcar (lambda (s) `',s) slot-names))))
  -            (cond
  -              ;; If they are :equal, then we need to make sure we
  -              ;; considered all the slots.
  -              ((not (eq :equal result)))
  -
  -              ;; If they are the same class, then we considered all the
  -              ;; slots.  We don't have to worry about subclasses because
  -              ;; subclasses would have their own method on compare.
  -              ((eq (class-of first) (class-of second))
  -               (assert (eq (find-class ',(class-name class)) (class-of first))))
  -
  -              ;; If second is a derived type, then first is less
  -              ((typep second (type-of first))
  -               (setf result :less))
  -
  -              ;; If first is a derived type, then first is greater
  -              ((typep first (type-of second))
  -               (setf result :greater))
  -
  -              ;; They are both derived types!  We've compared all their
  -              ;; common slots and didn't find an order, so they are
  -              ;; unequal.
  -              (t
  -               (setf result :unequal)))
  -            result)))
  -
  -    (eval
  -     `(defmethod make-load-form ((object ,(class-name class)) &optional environment)
  -          (make-load-form-saving-slots object :slot-names ',slot-names :environment environment)))))
  +  (let* ((superclasses (closer-mop:class-precedence-list class)))
  +    (unless (member (find-class 'data) superclasses)
  +      (error "data classes must inherit from data"))))
   
   (defmethod initialize-instance :around ((slot direct-data-slot) &rest initargs)
     (declare (ignore initargs))
  
positive.code: (defclass data-class (standard-class)
    ())
  
  (defmethod closer-mop:validate-superclass ((data-class data-class) superclass)
    (if (eq superclass (find-class 'standard-object))
        t
        (call-next-method)))
  
  
negative.code: (defmacro define-data (name direct-superclasses direct-slots &rest options)
    (when (find :metaclass options :key #'car)
      (error "metaclass option is forbidden"))
    (unless direct-superclasses
      (setf direct-superclasses '(data)))
    ;; We need to eval the class definition now so that the updater
    ;; functions are generated.
    `(eval-when (:compile-toplevel :load-toplevel :execute)
  