anchor.diff:                  (aif (parse-out-free-symbols x) (appending it)))
             (when (symbolp exp) (list exp)))))
   
  -(defun generate-match-code (exp)
  -   `(when (and *list* (print (list ,(car exp) *list*)) (eq ',(intern (string-upcase (car exp))) (car *list*)))
  -             (let ((*list* (cdr *list*)))
  -                   (print "matched!")
  -                   (match ,(cdr exp)))))
  +(defun generate-match-code (exp end)
  +   `(when (and list (eq ',(intern (string-upcase (car exp))) (car list)))
  +          (let ((list (cdr list)))
  +                ,(if end 'list `(match ,(cdr exp))))))
   
  -(defun generate-bind-code (exp)
  -   (with-gensyms (i v)
  -      `(iter (for ,i from 1 to (length *list*))
  -             (for ,v = (subseq *list* 0 ,i))
  -             (print (list ',(car exp) ,v))
  -             (setf ,(car exp) ,v)
  -             (when (let ((*list* (subseq *list* ,i))) 
  -                         (match ,(cdr exp)))
  -                   (leave t)))))
  +(defun generate-bind-code (exp end)
  +	(if end
  +		 `(when list (setf ,(car exp) list) t)
  +		 (with-gensyms (i v w)
  +         `(iter (for ,i from 1 to (length list))
  +				    (declare (fixnum ,i))
  +                (for ,v = (subseq list 0 ,i))
  +                (setf ,(car exp) ,v)
  +					 (for w = (let ((list (subseq list ,i))) (match ,(cdr exp))))
  +                (when w (leave w))
  +					 (finally (setf ,(car exp) nil) (return nil))))))
   
  -(defun generate-end-case ()
  -   `(not *list*)) ;; well, that was easy
  -
  -;; remember to add a list test and nil case
  -;; also, if the car of the list is a list (clause), so that doesn't get fucked by the expansion order
  -;; how to be decide to stop on the last sym case?
  -;;   test for nil list somehow, win if more than 0 or 1 iterations?
  -;;   top level should not stop until full list is matched!
  -;;     this makes greedy and lazy hard to implement
   (defmacro match (exp)
  -   (print `(match ,exp))
  -   (if (not exp)
  -       (generate-end-case)
  -       (if (listp (car exp))
  -           (aif (gethash (caar exp) destr-match-clauses)
  -                (funcall it (cdr exp) (cdar exp))) ;; ew 
  -           (if (stringp (car exp))
  -               (generate-match-code exp)
  -               (aif (gethash (car exp) destr-match-clauses)
  -                    (funcall it (cdr exp))
  -                    (generate-bind-code exp))))))
  +   (let ((end-of-chain? (not (cdr exp))))
  +		(if (listp (car exp))
  +			 (aif (gethash (caar exp) destr-match-clauses)
  +					(funcall it (cdar exp) (cdr exp) end-of-chain?)) ;; ew 
  +		    (if (stringp (car exp))
  +				  (generate-match-code exp end-of-chain?)
  +			     (generate-bind-code exp end-of-chain?)))))
   
   ;; clauses
   ;;   switch - matches forms, takes the first to work, analogous to parmesan choice
  -;;   lazy, greedy - only on top on a single binding form
   ;;   any - causes it to match zero or more list elements
   ;;   single - causes it to match only one form
  +;;   optional - if it matches, take that out of the list, keep matching either way,
  +;;     putting a single binding var at the end will break everything, as usual
   ;;   test - means the form must match the condition described as well as the structure of the match
   ;;   key - same as test, except the result of the function is bound instead of the normal result
   ;;   on-fail - expression to be returned by the whole thing if that subform fails to match
   
  -(def-match-clause single (rest var)
  -   (declare (ignore rest))
  -   `(when *list* 
  -           (setf ,var (car *list*))
  -           (let ((*list* (cdr *list*))) 
  -                 nil)))
  +(def-match-clause optional (forms rest end)
  +	(if end
  +		 `(match ,forms)
  +		 (with-gensyms (foo)
  +		    `(let ((,foo (match ,forms)))
  +					  (let ((list (if ,foo ,foo list)))
  +							  (if (eq ,foo t)
  +								   nil 
  +								   (match ,rest)))))))
  +
  +(def-match-clause single (var rest end)
  +	(if end
  +		 `(when (car list)
  +			 (setf ,(car var) (car list))
  +			 t)
  +		 `(when (car list)
  +			 (setf ,(car var) (car list))
  +			 (let ((list (cdr list)))
  +				    (match ,rest)))))
  +
  +(defun simple-pair (list val)
  +	(mapcar (lambda (x) (list x val)) list))
   
   ;; general process
   ;;   process the match-form
  
positive.code:  (:use cl alexandria iterate anaphora))
  (in-package destr-match)
  
  (defparameter destr-match-clauses (make-hash-table :test #'equalp))
  (defvar *list* nil)
  
  (defmacro def-match-clause (name ll &rest rest)
     `(setf (gethash ',name destr-match-clauses) (lambda ,ll ,@rest)))
  
negative.code: (proclaim '(optimize (speed 3) (safety 0) (debug 0) (space 3)))
  ;(declaim #+sbcl(sb-ext:muffle-conditions style-warning))
  ;(declaim #+sbcl(sb-ext:muffle-conditions warning))
  (setf *print-case* :downcase)
  