anchor.diff:  			  bindings)
   		  rest-var)))))
   
  +;;; Recall that the optional parameters of a parsed lambda list is
  +;;; either the keyword :none, or it is a list of &optional entries.
  +;;; Each optional entry has one of the two forms:
  +;;;
  +;;;  * (pattern init-arg)
  +;;;
  +;;;  * (pattern init-arg supplied-p-parameter)
  +;;;
  +;;; If the original lambda-list did not have an init-arg, the parsing
  +;;; process supplied NIL so that the parsed lambda list always has an
  +;;; init-arg.
  +;;;
  +;;; The HyperSpec says that if there is an &optional parameter and the
  +;;; object to be destructured "ends early", then the init-arg is
  +;;; evaluated and destructured instead.  We interpret this phrase to
  +;;; mean that either:
  +;;;
  +;;;   * the object to be destructured is NIL, in which case it "ends
  +;;;     early", and we destructure the init-arg instead.
  +;;;
  +;;;   * the object is a CONS, in which case the CAR of the object is
  +;;;     matched against the pattern.  If it doesn't match, then an
  +;;;     error is signaled and no attemp is made to match agains the
  +;;;     init-arg.
  +;;;
  +;;;   * the object is an atom other than NIL.  Then an error is
  +;;;     signaled.
   (defun destructure-optionals (optionals var)
     (if (or (eq optionals :none) (null optionals))
         (values '() var)
  
positive.code: 	 (final-env-var (if (eq env-var :none) (gensym) env-var))
  	 (form-var (gensym))
  	 (args-var (gensym)))
      `(lambda (,form-var ,final-env-var)
         ;; If the lambda list does not contain &environment, then
         ;; we IGNORE the GENSYMed parameter to avoid warnings.
         ;; If the lambda list does contain &envionrment, we do
         ;; not want to make it IGNORABLE because we would want a
         ;; warning if it is not used then. 
         ,@(if (eq env-var :none)
  	     `((declare (ignore ,final-env-var)))
  	     `())
         (let ((,args-var (cdr ,form-var)))
  	 (let* ,(destructure-lambda-list parsed-lambda-list args-var)
  	   ;; FIXME: insert ignorable variables introduced by
  	   ;; destrucuring here.
  	   ,@body)))))
  
  	 
  
negative.code: 	    (destructure-optionals (cdr optionals) temp1)
  	  (values (append `((,temp1 (if (consp ,var)
  					(cdr ,var)
  					(if (null ,var)
  					    '()
  					    (error "optional expected"))))
  			    ;; If the object is not a CONS, then it is
  			    ;; either NIL in which case we destructure
  			    ;; the init-arg instead, or else it is an
  			    ;; atom other than NIL and we have already
  			    ;; signaled an error before, so we don't
  			    ;; need to handle that case again.
  			    (,temp2 (if (consp ,var)
  					(car ,var)
  					,(cadr optional)))
  			    ;; If a supplied-p-parameter exists, then
  			    ;; we give it the value TRUE whenever the
  			    ;; object is a CONS, even though later
  			    ;; an error might be signaled because there
  			    ;; is no match. 
  			    ,@(if (consp (cddr optional))
  				  `((,(caddr optional) (consp ,var)))))
  			  (destructure-pattern (car optional) temp2)
  			  bindings)
  		  rest-var)))))
  
  ;;; Recall that the keys part of a compiled lambda list is either
  ;;; :none, which means that no &key was given at all, or a list if
  ;;; &key entries.  If the list is empty, it means that &key was given,
  ;;; but no &key parameters followed.
  ;;;
  ;;; A &key entry is either:
  ;;;
  ;;;  * ((keyword pattern) init-form)
  ;;; 
  ;;;  * ((keyword pattern) init-form supplied-p-parameter)
  ;;;
  ;;; The HyperSpec is pretty skimpy about what happens with keyword
  ;;; arguments ("the rest of the list ... is taken apart
  ;;; appropriately").  What we do is the following:
  ;;;
  ;;;  * If there is a keyword argument with the right keyword, then
  ;;;    its value is matched against the pattern.
  ;;;
  ;;;  * Otherwise, the value of the init-form is matched agains the
  ;;;    pattern.
  (defun destructure-keys (keys var)
    (if (or (eq keys :none) (null keys))
        '()
        (let ((key (car keys))
  	    (temp (gensym)))
  	(append `(;; What we do in step 1 depends on whether there is
  		  ;; a supplied-p-parameter or not.  If there is, then
  		  ;; in step 1, we return a list of two things:
  		  ;; 
  		  ;;  * a boolean indicating whether we found the
  		  ;;    keyword.
  		  ;;
  		  ;;  * either the argument found, or the value of the
  		  ;;    init-form if no argument was found.
  		  ;;
  		  ;; If there is no supplied-p-parameter, then we just
  		  ;; return the argument found or the value of the
  		  ;; init-form if no argument was found.
  		  (,temp
  		   ,(if (consp (cddr key))
  			`(loop for rem = ,var then (cddr rem)
  			       while (consp rem)
  