anchor.diff:  
   (defstruct expander
     macros
  +  argdefs
     pred
     call
     pre
  
positive.code:      (error "Atom expected as expander-name instead of ~A." expander-name))
    (| (atom name)
       (error "Atom expected as macro-name instead of ~A for expander ~A." name expander-name))
    (with-gensym g
      `(progn
         (& (expander-has-macro? ',expander-name ',name)
            (error ,(format nil "Redefinition of macro ~A in expander ~A." name expander-name)))
         (defun ,g ,args ,@body)
         (alet (expander-macros (expander-get ',expander-name))
           (= (href ! ',name) #',g)))))
  
  (defun expander-expand-once (expander-name x)
    (alet (expander-get expander-name)
  
negative.code:     (| pred (= (expander-pred !) [& (cons? _)
                                      (symbol? _.)
  	                                (expander-macro-function ! _.)]))
      (| call (= (expander-call !) [apply (expander-macro-function ! _.) (argument-expand-values 'expander-call (expander-macro-argdef ! _.) ._)]))
      (= (expander-lookup !)
         #'((expander name)
             (href (expander-macros expander) name)))))
  
  (defun set-expander-macro (expander-name name argdef fun &key (may-redefine? nil))
    (& (not may-redefine?)
       (expander-has-macro? expander-name name)
       (warn "Macro ~A already defined." name))
    (alet (expander-get expander-name)
      (= (href (expander-macros !) name) fun)
      (= (href (expander-argdefs !) name) (argument-expand-names 'set-expander-macro `,args))))
  
  (defun set-expander-macros (expander-name lst)
    (map [set-expander-macro expander-name _. ._] lst))
  