anchor.diff:  
   (defmethod serialize ((object standard-object) transaction-log)
     (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)
  -		 (format log-stream "#~d![" id)
  -		 (serialize (class-name (class-of object)) transaction-log)
  -		 (loop for info in (save-info object)
  -		       do (format log-stream " ")
  -			  (serialize (car info) transaction-log)
  -			  (format log-stream " ")
  -			  (serialize (funcall (cadr info) object)
  -				     transaction-log))
  -		 (format log-stream "]"))
  -	  (format log-stream "#~d^" id)))))
  +                   (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)
  +                 (format log-stream "#~d![" id)
  +                 (serialize (class-name (class-of object)) transaction-log)
  +                 (loop for info in (save-info object)
  +                       do (format log-stream " ")
  +                          (serialize (car info) transaction-log)
  +                          (format log-stream " ")
  +                          (serialize (funcall (cadr info) object)
  +                                     transaction-log))
  +                 (format log-stream "]"))
  +          (format log-stream "#~d^" id)))))
   
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   ;;;
   ;;; Open a transaction log.
   ;;;
  -;;; The readtable used to read a transaction contains three additional
  -;;; reader macros, associated with #!, #^ and [. 
  +;;; This is a compound function that first calls LOAD-TRANSACTION-LOG
  +;;; to load a transaction log from disk and execute the provided
  +;;; function on its contents, then utilizes the object-table modified
  +;;; in effect of the first function to create a transaction log object
  +;;; which can be used to log further transactions.
  +
  +(defun open-transaction-log (filename function)
  +  (let ((object-table (make-hash-table)))
  +    (load-transaction-log filename function object-table)
  +    (make-transaction-log filename object-table)))
  +
  +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  +;;;
  +;;; Load a transaction log.
  +;;;
  +;;; This function reads the transaction log from disk.
   ;;;
   ;;; After a transaction has been read, the function supplied by the
   ;;; application is called in order to execute the transaction.
   
  -(defun open-transaction-log (filename function)
  -  (let ((object-table (make-hash-table)))
  -    (with-open-file (stream filename
  -			    :direction :input
  -			    :if-does-not-exist :create)
  -      (let ((*readtable* (copy-readtable)))
  -	(set-macro-character
  -	 #\[
  -	 (lambda (stream char)
  -	   (declare (ignore char))
  -	   (apply #'make-instance (read-delimited-list #\] stream t))))
  -	(set-syntax-from-char #\] #\))
  -	(set-dispatch-macro-character
  -	 #\# #\!
  -	 (lambda (stream char param)
  -	   (declare (ignore char))
  -	   (setf (gethash param object-table)
  -		 (read stream nil nil t))))
  -	(set-dispatch-macro-character
  -	 #\# #\^
  -	 (lambda (stream char param)
  -	   (declare (ignore stream char))
  -	   (gethash param object-table)))
  -	(loop for transaction = (read stream nil nil)
  -	      until (null transaction)
  -	      do (funcall function transaction))))
  -    (let ((object-id-table (make-hash-table :test #'eq))
  -	  (max-object-id 0)
  -	  (stream (open filename
  -			:direction :output
  -			:if-exists :append)))
  -			
  -      (maphash (lambda (object-id object)
  -		 (setf (gethash object object-id-table) object-id)
  -		 (setf max-object-id (max max-object-id object-id)))
  -	       object-table)
  +(defun load-transaction-log (filename function object-table)
  +  (with-open-file (stream filename
  +                          :direction :input
  +                          :if-does-not-exist :create)
  +    (let ((*readtable* (copy-readtable)))
  +      (set-syntax *readtable* object-table)
  +      (loop for transaction = (read stream nil nil)
  +            until (null transaction)
  +            do (funcall function transaction)))))
  +
  +;;; This function returns two values: the object identity table which
  +;;; is required for creating the transaction log object and the
  +;;; maximum object ID present in the table. Integers above this
  +;;; number are free for assignment in subsequent transactions.
  +
  +(defun make-object-id-table (object-table)
  +  (let* ((object-id-table (make-hash-table :test #'eq))
  +         (max-object-id 0)
  +         (fn (lambda (object-id object)
  +               (setf (gethash object object-id-table) object-id
  +                     max-object-id (max max-object-id object-id)))))
  +    (maphash fn object-table)
  +    (values object-id-table max-object-id)))
  +
  +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  +;;;
  +;;; Make the transaction log object.
  +;;;
  +;;; This function takes an object table, creates an object identity
  +;;; table based on its context, and uses the ID table to create a
  +;;; transaction-log object that will be used to log new transactions.
  +
  +(defun make-transaction-log (filename object-table)
  +  (multiple-value-bind (object-id-table max-object-id)
  +      (make-object-id-table object-table)
  +    (let ((stream (open filename
  +                        :direction :output
  +                        :if-exists :append)))
         (make-instance 'transaction-log
  -	:log-stream stream
  -	:object-id-table object-id-table
  -	:next-object-id (1+ max-object-id)))))
  +                     :log-stream stream
  +                     :object-id-table object-id-table
  +                     :next-object-id (1+ max-object-id)))))
  +
  +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  +;;;
  +;;; Syntax-setting functions for the transaction log loader.
  +;;;
  +;;; The readtable used to read a transaction contains three additional
  +;;; reader macros, associated with #!, #^ and [.
  +
  +(defun set-syntax (readtable object-table)
  +  (let ((*readtable* readtable))
  +    (%set-syntax-left-bracket )
  +    (%set-syntax-right-bracket)
  +    (%set-syntax-hash-bang object-table)
  +    (%set-syntax-hash-caret object-table)))
  +
  +(defun %set-syntax-left-bracket ()
  +  (set-macro-character
  +   #\[
  +   (lambda (stream char)
  +     (declare (ignore char))
  +     (apply #'make-instance (read-delimited-list #\] stream t)))))
  +
  +(defun %set-syntax-right-bracket ()
  +  (set-syntax-from-char #\] #\)))
  +
  +(defun %set-syntax-hash-bang (object-table)
  +  (set-dispatch-macro-character
  +   #\# #\!
  +   (lambda (stream char param)
  +     (declare (ignore char))
  +     (setf (gethash param object-table)
  +           (read stream nil nil t)))))
  +
  +(defun %set-syntax-hash-caret (object-table)
  +  (set-dispatch-macro-character
  +   #\# #\^
  +   (lambda (stream char param)
  +     (declare (ignore stream char))
  +     (gethash param object-table))))
   
   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   ;;;
  
positive.code: 
  (defun close-transaction-log (transaction-log)
    (close (log-stream transaction-log)))
  
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  
negative.code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  ;;; Serialization.
  ;;;
  ;;; What we are doing is essentially a duplication of what
  ;;; print-object is doing, because unfortunately, there is no portable
  ;;; way of using print-object to accomplish what we want.
  
  (defgeneric serialize (object transaction-log))
  
  