anchor.diff:                                :left first
                                 :right second))))))
   
  +(defun rope-list-cat (list)
  +  (cond
  +    ((null list)
  +     nil)
  +    ((null (cdr list))
  +     (car list))
  +    ((null (cddr list))
  +     (%rope (first list) (second list)))
  +    (t
  +     (rope-list-cat (loop for rest = list then (cddr rest)
  +                       while rest
  +                       collect (%rope (first rest) (second rest)))))))
  +
  +(defun rope-array-cat (array
  +                       &key
  +                         (start 0)
  +                         (end (length array)))
  +  (declare (type non-negative-fixnum start end)
  +           (type array array))
  +  (cond
  +    ((= (1+ start) end)
  +     (aref array start))
  +    ((>= start end)
  +     nil)
  +    (t
  +     (let ((midpoint (truncate (+ start end) 2)))
  +       (%rope (rope-array-cat array :start start :end midpoint)
  +              (rope-array-cat array :start midpoint :end end))))))
  +
   (defun rope-cat (sequence)
     "Concatenate all ropes in SEQUENCE."
  -  (reduce #'%rope-cat sequence))
  -
  +  (etypecase sequence
  +    (array (rope-array-cat sequence))
  +    (list (rope-list-cat sequence))))
   
   (declaim (inline rope))
   (defun rope (&rest args)
     "Concatenate all ropes in ARGS."
     (declare (dynamic-extent args))
  -  (when args (rope-cat args)))
  +  (when args (rope-list-cat args)))
   
   (defun rope-string (rope &key (element-type 'character))
     "Convert the rope to a string."
  
positive.code:   '|
  |)
  
  (defstruct rope-node
    (length 0 :type non-negative-fixnum)
    (height 1 :type (integer 1 #.most-positive-fixnum))
    (left nil :type rope)
    (right nil :type rope))
  
  
negative.code:     (rope-node (rope-node-height rope))))
  
  (declaim (inline %rope-length-height))
  
  (defun %rope-length-height (rope)
    (etypecase rope
      (rope-node
  