anchor.diff:  	   :name 'nbutlast))
     (if (= n 1)
         (nbutlast-1 list)
  -      (let ((length (loop for conses = list then (cdr conses)
  +      (let ((length (loop for slow on list
  +			  with conses = list
                             until (atom conses)
  -                          count t)))
  +                          count t
  +			  do (setf conses (cdr conses))
  +                          until (atom conses)
  +                          count t
  +			  do (setf conses (cdr conses))
  +			  do (when (eq slow conses)
  +			       ;; we have a circular list
  +			       (error 'must-be-proper-or-dotted-list
  +				      :datum list
  +				      :name 'nbutlast)))))
           (if (<= length n)
               nil
               (progn (setf (cdr (nthcdr (- length (1+ n)) list)) nil)
  
positive.code: ;;; This condition is used by functions and macros that require
  ;;; some list to be either a proper list or a circular list.
  (define-condition must-be-proper-or-circular-list (type-error name-mixin)
    ()
    (:default-initargs :expected-type 'list))
  
  
negative.code:       (let ((a list)
              (b (cdr list))
              (c (cddr list)))
          (loop for slow on list
  	      until (atom c)
                do (setf a b
                         b c
                         c (cdr c))
  	      until (atom c)
                do (setf a b
                         b c
                         c (cdr c))
  	      do (when (eq slow c)
  		   ;; we have a circular list
  		   (error 'must-be-proper-or-dotted-list
  			  :datum list
  			  :name 'nbutlast)))
  	(setf (cdr a) nil)
          list)))
  
  ;;; FIXME: The HyperSpec says that we must signal a type-error
  