[plt-scheme] Understanding readtables

From: Mark Engelberg (mark.engelberg at gmail.com)
Date: Fri Jul 4 16:15:28 EDT 2008

My son wants to extend the readtable, and I'm trying to help him out.
I've found the appropriate spot in the docs, but find it somewhat
confusing.  I'm hoping someone here can help us understand this
better.

He's got a struct called a bundle, which stores an expression in both
its unevaluated form and its evaluation, and a macro that serves as a
constructor.

It looks like this:
(define-syntax bundle
  (syntax-rules ()
    ((bundle expr)
     (make-<bundle> (quote expr) expr))))
(define (bundle-write b p write?)
  (fprintf p "#*(~a . ~a)" (<bundle>-e b)(<bundle>-a b)))
(define-struct <bundle> (e a) #:property prop:custom-write bundle-write)
(define bundle? <bundle>?)
(define bundle-expr <bundle>-e)
(define bundle-answer <bundle>-a)

Okay, now he's created a custom write function that displays a bundle
as #*((+ 1 2) . 3)

He wants to customize the reader so that he can read back in this
printed version of the bundle, sort of like #(1 2 3) for making
vectors, or #hash((1 . 2)) for making a hash table.  He ideally
envisions that the reader would handle either #*((+ 1 2) . 3) or #*((+
1 2)) and it will return #*((+ 1 2) . 3) both ways (the second version
evaluates the expression automatically when it has not been when the
evaluation has not been provided).  [Yes, I know that having the first
case breaks encapsulation, but this is what he wants, in large part,
just to understand how it could be done].

So from the documentation, it sounds like he needs to extend the
readtable with a dispatch-macro, that calls a special reading function
that will be called when the reader is called for #*.  Something like:

(current-readtable (make-readtable (current-readtable) #\*
'dispatch-macro readerbundle))

But this doesn't quite work, and it's not really clear what form this
reader function needs to take.  Can someone set us on the right path
here?

Thanks,

Mark


Posted on the users mailing list.