(defun serialize-common (object transaction-log fn) (with-accessors ((object-id-table object-id-table) (next-object-id next-object-id) (log-stream log-stream)) transaction-log (let ((id (gethash object object-id-table))) (if (null id) (progn (setf id (incf next-object-id)) (setf (gethash object object-id-table) id) (funcall fn object id log-stream transaction-log)) (format log-stream "#~d^" id))))) (defmacro with-serialize-common ((object transaction-log id log-stream) &body body) `(serialize-common object transaction-log (lambda (,object ,id ,log-stream ,transaction-log) ,@body))) (defmethod serialize ((object cons) transaction-log) (with-serialize-common (object transaction-log id log-stream) (format log-stream "#~d!(" id) (serialize (car object) transaction-log) (format log-stream " . ") (serialize (cdr object) transaction-log) (format log-stream ")"))) (with-output-to-string (output-stream) (let ((transaction-log (make-transaction-log output-stream (make-hash-table)))) (serialize (cons 'a 'b) transaction-log))) ;;; "#2!(CLOBBER::A . CLOBBER::B)"