anchor.diff:        (otherwise       (error "something went very wrong"))))
   
   (defun generate-match-code (exp end)
  -   `(when (and list ,(match-test (car exp)))
  -         ,(if end 't
  -            `(let ((list (cdr list)))
  -                   (match ,(cdr exp))))))
  +  `(when (and list ,(match-test (car exp)))
  +        ,(if end 't
  +           `(let ((list (cdr list)))
  +                  (match ,(cdr exp))))))
   
   (defun generate-atom-code (exp end)
  -   `(when (and list (equalp ,(car exp) (car list)))
  -         ,(if end 't
  -            `(let ((list (cdr list)))
  -                   (match ,(cdr exp))))))
  -
  -(defun generate-bind-code (exp end)
  -   (if end
  -       `(when list (setf ,(car exp) list) t)
  -       (with-gensyms (v x w r loop succeed fail end)
  -         `(let ((,v (list (car list))) (,x (cdr list)) (,w nil) (,r nil))
  +  `(when (and list (equalp ,(car exp) (car list)))
  +        ,(if end 't
  +           `(let ((list (cdr list)))
  +                  (match ,(cdr exp))))))
  +
  +;; here be dragons
  +(defun generate-bind-body (sym rest type &optional fun)
  +   (if single-mode
  +       nil
  +       (with-gensyms (x w r f loop succeed fail end)
  +         `(let ((,x (cdr list)) (,w nil) (,r nil))
  +                (setf ,sym (list (car list)))
                   (tagbody
                     ,loop
  -                     (when (not ,x) (go ,fail))
  -                     (setf ,w (let ((list ,x)) (match ,(cdr exp))))
  -                     (when (eq ,w t) (go ,succeed))
  -                     (appendf ,v (list (car ,x)))
  -                     (setf ,x (cdr ,x))
  -                     (go ,loop)
  +                      (when (not ,x) (go ,fail))
  +                      (setf ,w (let ((list ,x)) (match ,rest)))
  +                     ,(case type
  +                         (normal `(when (eq ,w t) (go ,succeed)))
  +                         (test   `(when (and (eq ,w t) (funcall ,fun ,sym)) (go ,succeed)))
  +                         (key    `(let ((,f (funcall ,fun ,sym)))
  +                                        (when (and (eq ,w t) ,f)
  +                                              (setf ,sym ,f) (go ,succeed)))))
  +                      (appendf ,sym (list (car ,x)))
  +                      (setf ,x (cdr ,x))
  +                      (go ,loop)
                     ,fail
  -                     (setf ,(car exp) nil)
  -                     (setf ,r nil)
  -                     (go ,end)
  +                      (setf ,sym nil)
  +                      (setf ,r nil)
  +                      (go ,end)
                     ,succeed
  -                     (setf ,(car exp) ,v)
  -                     (setf ,r ,w)
  +                      (setf ,r ,w)
                     ,end)
  -                ,r))))
  +               ,r))))
  +
  +(defun generate-bind-code (exp end)
  +   (if end
  +      `(when list (setf ,(car exp) list) t)
  +       (generate-bind-body (car exp) (cdr exp) 'normal)))
   
   (defmacro match (exp)
      (let ((end-of-chain? (not (cdr exp))))
  
positive.code: (in-package destr-match)
  
  ;; TODO
  ;; [x] MAKE THE PACKAGE NAME MATCH THE SYSTEM NAME
  ;; [x] neat switch macro
  ;; [ ] fill out the README with examples and documentation
  ;; [ ] sublists?
  ;; [x] make special parsing for single inside test and key
  ;; [x] make switch (list) raw forms, so everything still works
  ;; [ ] modify match so clause names without arguments are bindings
  ;; [ ] full literal value matching, using quotes for symbols?
  ;; [ ] fix indentation and maybe line length
  
  (defparameter destr-match-clauses (make-hash-table :test #'equalp))
  (defparameter matching-style 'symbol) ;; symbol, string, case-sensitive, regex, symbol-regex
  
  (defmacro def-match-clause (name ll &rest rest)
     `(setf (gethash ,(string name) destr-match-clauses) (lambda ,ll ,@rest)))
  
negative.code: 
  (defun expand-macros (exp)
     (if (and (listp exp) (symbol? (car exp)))
         (or (when (gethash (string (car exp)) destr-match-clauses) 
                   (if (member (car exp) '(test key) :test #'symbol-eq) 
                       (list (first exp) (expand-macros (second exp)) (third exp)) 
                       (cons (car exp) (mapcar #'expand-macros (cdr exp)))))
             (multiple-value-bind (a b) (macroexpand-1 exp)
                (when b (expand-macros a)))
             (mapcar #'expand-macros exp))
         (if (symbol? exp) 
  