anchor.diff:                       (gensym "CALL"))))
   
   ;; TODO: add timeout and keepalive parameters if it seems reasonable
  -(defun invoke-rpc-method (sock service method args &key notification)
  +(defun invoke-rpc-method (con service method args &key notification)
     (let ((call (make-call-obj service method args)))
       (declare (special *rpc-batch*))
       ;; if *rpc-batch* is bound, just add the call to it
  
positive.code:         (write-request (socket con) (list call)))
      (if notification
          (values)
          (make-result-future (rpc-call-id call) sock))))
  
  (defmacro with-batch-calls ((stream &optional (batch-req nil batch-supplied-p)) &body body)
    `(let ((*rpc-batch* ,(if batch-supplied-p batch-req '())))
  
negative.code:       (setf (gethash id bucket) result)
        (values))))
  
  ;; TODO: Error approach: set error-status/condition on connection on
  ;; read; when a future completes later, it will either return the
  ;; received result (if one was retrieved without error), or re-signal
  ;; the stored condition (is it reasonable to re-throw the same
  ;; condition more than once? What if error handling has been done
  ;; in-between?).
  (defun read-result-with-id (con id)
    "Read responses from CON, storing results until a request containing
  a response with id ID arrives. Will process all results in a response
  before returning."
    ;; TODO: this is probably not the right thing to do, and has case issues
    (let ((id (if (symbolp id)
                  (string-downcase (symbol-name id))
                  id))
          (bucket (result-bucket con)))
      (loop until (has-key id bucket)
         with response = (read-response con)
         ;; a response is a list of results
         do (mapc #'(lambda (r) (add-result con r))
                  response))
      ;; Return the result and remove it from the bucket
      (prog1 (gethash id bucket)
        (remhash id bucket))))
  
  (defun make-result-future (con id)
    "Return a future that produces a result with an id of ID from CON."
    (lambda ()
      (read-response-with-id con id)))
  
  (defun wait (future)
    "Wait for a future to complete, then return it's value."
  