anchor.diff:  `undefiner'. If it isn't, the results are undefined. `Syntax' is
   the Lisp syntax object that has `definition-form'."))
   
  +(defvar *undefiners* (make-hash-table)
  +  "A hash table mapping operators to undefiners. The undefiners
  +are instances of `undefiner'.")
  +
  +(defun get-undefiner (definition-type)
  +  "Return the undefiner for `definition-type', which must be a
  +symbol. Returns NIL if there is no undefiner of the given type."
  +  (values (gethash definition-type *undefiners*)))
  +
  +(defun invalid-form-for-type (syntax form type-name)
  +  "Signal a `form-conversion-error' describing the fact that
  +`form' cannot define a `type-name'."
  +  (form-conversion-error syntax form "Form cannot define a ~A." type-name))
  +
  +(defun invalid-form (undefiner syntax form)
  +  "Signal a `form-conversion-error' describing the fact that
  +`form' cannot define whatever kind of definition `undefiner'
  +handles."
  +  (invalid-form-for-type syntax form (undefiner-type undefiner)))
  +
   (defclass simple-undefiner (undefiner)
     ((%undefiner-type :reader undefiner-type
                       :initform (error "A description must be provided.")
  
positive.code:   (funcall (undefiner-function undefiner) syntax
             (definition-name undefiner syntax form)
             form))
  
  (defvar *undefiners* (make-hash-table)
    "A hash table mapping operators to undefiners. The undefiners
  are instances of `undefiner'.")
  
  (defun get-undefiner (definition-type)
    "Return the undefiner for `definition-type', which must be a
  symbol. Returns NIL if there is no undefiner of the given type."
    (values (gethash definition-type *undefiners*)))
  
  (defmacro define-simple-undefiner (definition-spec (syntax-sym name-sym form-sym) &body body)
    "Define a way to undefine some definition. `Definition-spec' is
  
negative.code:             :undefiner-function #'(lambda (,syntax-sym ,name-sym ,form-sym)
                                      (declare (ignorable ,syntax-sym ,name-sym ,form-sym))
                                      ,@body)))))
  
  (defclass generic-undefiner (undefiner)
    ((%undefiner-type :reader undefiner-type
                      :initform (error "A description must be provided.")
                      :type string
                      :documentation "A textual, user-oriented name
  for the type of definition handled by this
  undefiner."
                      :initarg :undefiner-type)
     (%name-function :reader name-function
                     :initform (error "A name retrieval function must be provided.")
                     :documentation "A function of three arguments:
  the syntax object and the form to retrieve a name from. Should
  return the name as a Lisp object (probably a symbol). Should
  signal a `form-conversion-error' if the form cannot define
  whatever type this undefiner handles."
                     :initarg :name-function)
     (%undefiner-function :reader undefiner-function
                          :initform (error "An undefiner function must be provided.")
                          :documentation "A function of three
  arguments: the syntax object, the name of the definition to be
  undefined and the form to be undefined."
                          :initarg :undefiner-function)))
  
  (defmethod definition-name ((undefiner generic-undefiner) (syntax lisp-syntax) (form form))
    (funcall (name-function undefiner) syntax form))
  
  (defmethod undefine ((undefiner generic-undefiner) (syntax lisp-syntax) (form form))
    (funcall (undefiner-function undefiner) syntax
             (definition-name undefiner syntax form)
             form))
  
  (defmacro define-undefiner (definition-spec
                              ((name-syntax-sym name-form-sym) &body name-body)
                              ((undef-syntax-sym undef-name-sym undef-form-sym)
                               &body undefiner-body))
    "Define a way to undefine definitions. `Definition-spec' is the
  operator (like `defun', `defclass', etc) and may optionally be a
  list, in which case the first element is the operator, and the
  second a user-oriented name for the kind of thing defined by the
  operator. `Name-body' and `Undefiner-body' will be evaluated to
  retrieve the name and perform the undefinition, respectively.
  
  `Name-syntax-sym' and `name-form-sym' will be bound to the Lisp
  syntax instance and the entire form of the definition during
  evaluation of `name-body'. Syntactical problems (such as an
  incomplete or invalid form) should be signalled by an
  invocation `(invalid)'
  
  `undef-syntax-sym', `undef-name-sym' and `undef-form-sym' will be
  bound to the Lisp syntax instance, the name of the definition to
  be undefined and the entire form of the definition when
  `undefiner-body' is evaluated. Syntactical problems (such as an
  incomplete or invalid form) should be signalled by an
  invocation `(invalid)'."
    (check-type definition-spec (or list symbol))
    (let* ((definition-type (unlisted definition-spec))
           (undefiner-name (if (listp definition-spec)
                               (second definition-spec)
                               (string-downcase definition-type))))
      (check-type definition-type symbol)
      `(setf (gethash ',definition-type *undefiners*)
             (make-instance 'generic-undefiner
              :undefiner-type ,undefiner-name
              :name-function #'(lambda (,name-syntax-sym ,name-form-sym)
                                 (declare (ignorable ,name-syntax-sym ,name-form-sym))
                                 (flet ((invalid ()
                                          (invalid-form-for-type ,name-syntax-sym ,name-form-sym ,undefiner-name)))
                                   (declare (ignorable #'invalid))
                                   ,@name-body))
              :undefiner-function #'(lambda (,undef-syntax-sym ,undef-name-sym ,undef-form-sym)
                                      (declare (ignorable ,undef-syntax-sym ,undef-name-sym ,undef-form-sym))
                                      (flet ((invalid ()
                                               (invalid-form-for-type ,undef-syntax-sym ,undef-form-sym ,undef-name-sym)))
                                        (declare (ignorable #'invalid))
                                        ,@undefiner-body))))))
  
  (define-simple-undefiner (defun "function") (syntax name form)
    (fmakunbound name))
  