Subject: bug#11198: problems reading data with a "read-hash-extend" registered reader

From: Klaus Stehle <[email-masked]>
Date: Sat, 7 Apr 2012 22:16:06 +0200 (CEST)

Hi,

;;;; an example script to describe the problem
;;;; writing and reading records:

(use-modules (srfi srfi-9))

;; define a record as example
(define-record-type my-record
  (make-my-record one two)
  my-record?
  (one my-one)
  (two my-two))

;; fix another guile-2.0 bug
(if (string>= (version) "2")
    (struct-set! my-record (+ 2 vtable-offset-user) make-my-record))

;; the record write function
(define (record-printer s p)
  (let* ((rtd (record-type-descriptor s))
         (lst (apply append
                     (map (lambda (f) (list (symbol->keyword f)
                                            ((record-accessor rtd f) s)))
                          (record-type-fields rtd)))))
    (format p "#R~S" (cons (record-type-name rtd) lst))))

(struct-set! my-record vtable-index-printer record-printer)

;; the record read function
(define (read-R chr port)
  (let ((rlst (read port)))
    (if (not (pair? rlst))
        #f
        (let* ((name (car rlst))
               (lst (cdr rlst))
               (rtd (primitive-eval name))
               (fields (record-type-fields rtd)))
          (apply (record-constructor rtd)
                 (map (lambda (f) (let ((kl (memq (symbol->keyword f) 
lst)))
                                    (if (and kl (pair? (cdr kl)))
                                        (cadr kl)
                                        #f))) fields))))))

(read-hash-extend #\R read-R)

;; test-1: writing and reading records is working well ...
(define rec (make-my-record "bla" "bobo"))

(let ((opo (open-output-file "rec.data")))
  (write rec opo)
  (close-output-port opo))

(let ((ipo (open-input-file "rec.data")))
  (let ((data (read ipo)))
    (format #t "--> ~S~%" rec)
    (close-input-port ipo)))

;; test-2: ... but this doesn't work properly
(define rec #R(my-record #:two "bobo" #:one "bla"))
(format #t "==> ~S~%" rec)

;; end of script

The behavour of test-2 is very strange. If the script is running
from a file, there is a compiler error message, but the record is built
and displayed.

If we start the script with the -l option and enter the line
afterwards manually into the REPL ...

(define rec #R(my-record #:two "bobo" #:one "bla"))

... there is another cryptic error message:

=> While compiling expression:
=> ERROR: build-constant-store: unrecognized object
   #R(my-record #:one "bla" #:two "bobo")

We can see our record built correctly in the error message! But the record
remains unreachable.

Using guile-1.8 all these things are running perfectly!

Cheers,
Klaus Stehle

----------------------------
guile --version
guile (GNU Guile) 2.0.5

uname -srm
Linux 2.6.32-5-amd64 x86_64