[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
> (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
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
There is an implied global table mapping uids to record-type-descriptors
but no other table.
More information about the R6RS