[R6RS] relationships between uid, <record name>, and rtd

dyb at cs.indiana.edu dyb at cs.indiana.edu
Wed Mar 8 10:31:26 EST 2006

> A programmer can obtain a record-type descripter
> from a record-name via
> (record-type-descriptor <record name>) (syntax)
>     This evaluates to the record-type descriptor associated with
>     the type specified by <record-name>.
>     Note that record-type-descriptor works on both opaque and
>     non-opaque record types.
> A programmer can also obtain a name from a record-type-descriptor
> via
> (record-type-name rtd)
>     Returns the name of the record-type descriptor rtd.
> I foolishly assumed that the record-type-descriptor and the
> record-type-name procedure would be inverses, but maybe they
> aren't.  If not, then what is the relationship?

record-type-descriptor is syntax that maps an identifier bound by
define-record-type to the record-type descriptor created for that type. 
The output of

  (define-record-type (foo make-foo foo?) (fields (immutable x get-x)))

might look something like this:

    (define-somehow foo <info about this record>)
    (define foo-rtd (make-record-type-descriptor ---))
    (define make-foo ---)
    (define foo ---)
    (define get-x ---))

where define-somehow adds a binding to the expand-time and/or run-time
environment that both define-record-type and record-type-descriptor know
how to access.  foo-rtd is an introduced, hence "fresh" identifier.  Then

  (record-type-descriptor foo)

would expand into


On the other hand, record-type-name is a procedure that returns the
(documentary) name of the type as a symbol.  Even if you have a way to
turn this into an identifier (e.g., via eval), the identifier will not be
bound to the type if the type was created by make-record-type.  For
example, you might try:

  (define alpha (make-record-type-descriptor 'frobrat ---))
  (eval `(define-record-type (bar make-bar bar?)
           (parent ,(record-type-name alpha))))

but this would fail, because frobrat isn't bound to anything.

So the two are not inverses in any sense.

> BTW, what kind of object is returned by the record-type-name
> procedure?  The explicit-naming spec says
>     <Record name>, <constructor name>, and <predicate name> must all
>     be identifiers.
>     <Record name> becomes the name of the record type. Additionally,
>     it is bound by this definition to an expand-time or run-time
>     description of the record type for use as parent name in
>     syntactic record-type definitions that extend this definition.
>     It may also be used as a handle to gain access to the underlying
>     record-type descriptor and constructor descriptor (see
>     record-type-descriptor and record-constructor-descriptor below).
> But how can the record-type-name return an identifier?  I think
> it would have to return a symbol.

Yes, it should return a symbol.  In fact, I think the text you quote once
read something like "<Record name>, taken as a symbol, becomes the name of
the record ...".  We should stick something like that back in.

> If the record-type-descriptor
> syntax and the record-type-name procedure are inverses, then I
> think <record name> would just be a symbol.

> If a <record name> is just a symbol, however, then there must be
> some global table mapping symbols to record-type-descriptors.
> Obviously there must be some such table for non-generative record
> types, but why require such a thing for generative types?

They are not inverses, <record name> is an identifier (used as a symbol in
the implied call to make-record-type-descriptor, but bound as an
identifier to information about the record type), and there is no need for
such a table.

> Furthermore the procedural interface seems to imply some global
> table mapping uids to record-type-descriptors.  Am I right about
> that?  If so, what is the relationship between these two global
> tables?

There is an implied global table mapping uids to record-type-descriptors
but no other table.


More information about the R6RS mailing list