anchor.diff:      ((or :keyword :facing)
        `(intern (string-upcase ,arg) :keyword))
       (:table 
  -     (lookup-exp arg '(private-tables *server*) '(public-tables *server*)))
  +     (lookup-expression arg '(private-tables *server*) '(public-tables *server*)))
       ((list :list _)
        `(loop for elem in (decode-json-from-string ,arg)
   	 collect (gethash elem (things table))))
       ((or :stack :flippable :placeable
   	 (list :card :from-table))
  -     (lookup-exp arg '(things table)))
  +     (lookup-expression arg '(things table)))
       ((list :card :from-hand)
  -     (lookup-exp arg '(hand *player*)))
  +     (lookup-expression arg '(hand *player*)))
       (_ (error "Invalid type label: '~a'" type))))
   
  -(defun lookup-exp (arg &rest places)
  +(defun lookup-expression (arg &rest places)
     (with-gensyms (sym)
       `(let ((,sym (intern (string-upcase ,arg) :keyword)))
          (or ,@(loop for p in places
   		collect `(gethash ,sym ,p))))))
   
  -(defun lookup-assn (arg type)
  +(defun lookup-assertion (arg type)
     (match type
       (:table `(assert (typep ,arg 'table)))
       (:stack `(assert (typep ,arg 'stack)))
  
positive.code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;;;;;;;; All for the custom define-handler
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  (defun type-exp (arg type)
    "Given a symbol name and a type, returns the expression to read that type from a string"
    (match type
      (:string 
  
negative.code: - The names (for use as final args)
  - The lookup assertions"
    (loop for (name type) in args
       for table? = (eq type :table)
       for t-exp = (type-expression name type)
       for assn = (lookup-assertion name type)
       collect name into arguments 
       if table? collect (list name t-exp) into table-lookups and collect assn into table-assertions
       when (and (not table?) t-exp) collect (list name t-exp) into type-expressions
       when (and (not table?) assn) collect it into assertions
       finally (return (values arguments table-lookups table-assertions type-expressions assertions))))
  
  (defmacro define-handler ((name) (&rest args) &body body)
    "Defines handlers with an eye for self-documentation, DRY and portability"
    (let* ((uri (concatenate 'string "/" (string-downcase (symbol-name name)))) 
  	 (opts `(,name :uri ,uri)))
      (multiple-value-bind (final-args table-lookups table-assertions type-conversions lookup-assertions) (type-pieces args)
        `(progn
  	 (setf (gethash ,uri *handlers*) '(,@args))
  	 ,(if (not args)
  	      `(define-easy-handler ,opts nil (encode-json-to-string (progn ,@body)))
  	      (if (and (eq (caar body) 'with-lock-held) table-lookups)
  		  `(define-easy-handler ,opts ,final-args
  		     (assert (and ,@final-args))
  		     (let* ,table-lookups
  		       ,@table-assertions
  		       (with-lock-held ,(cadar body)
  			 (let* ,type-conversions
  			   ,@lookup-assertions
  			   (encode-json-to-string (progn ,@(cddar body)))))))
  		  `(define-easy-handler ,opts ,final-args
  		     (assert (and ,@final-args))
  		     (let* ,(append table-lookups type-conversions)
  		       ,@(append table-assertions lookup-assertions)
  		       (encode-json-to-string ,@body)))))))))
  
  (defmacro define-sse-handler ((name) (&rest args) &body body)
    `(define-handler (,name) (,@args)
  