My wording in my last post below was hurried.  Let me elaborate better.

If you think "record type" is distinct from "record type descriptor",
and "record type definition" is only via define-record-type and not via
make-record-type-descriptor, then some of the wording/design in R6RS
might be more clear to you.  But, the beginning of R6RS Libraries
Chapter 6 definitely gives the impression "record type" and "record type
descriptor" are the same.

The spec for define-condition-type does say it "expands into a
record-type definition for a record type <condition-type> (see section
6.2)", and section 6.2 is Syntactic Layer.  I suppose the interpretation
of this could be stretched as meaning define-condition-type uses only
define-record-type (which would resolve the issue about
record-type-descriptor used on condition types), but that meaning is not
obvious, especially given the ambiguity about what a "record-type
definition" and "record type" are and what "(see section 6.2)" means.

Regardless of word-twisting, I think Will Clinger's main point is that
record types should always be record type descriptors so that it's not
necessary to determine whether a "record type" thing is a first-class
run-time descriptor or an expand-time handle.  With R6RS, it's necessary
to know if you need to use record-type-descriptor or not and whether you
need to use parent-rtd or parent.  I think the argument is that this
breaks the abstraction of "record type" in an unacceptable way.

For example, my matcher matches records, and to support "record type"
things made with either define-record-type or
make-record-type-descriptor, I have to have special syntax to
distinguish whether the given record type is an expand-time handle or
evaluates to a run-time descriptor:

> (define A (make-record-type-descriptor 'A #F #F #F #F '#()))
> (match 1
    ((:record A) 'record)
    (_ 'nope))
Unhandled exception
 Condition components:
   1. &who: record-type-descriptor
   2. &message: "not a record type"
   3. &syntax:
       form: (record-type-descriptor A)
       subform: #f
   4. &trace: #<syntax (record-type-descriptor A)>
   5. &trace: #<syntax (match-lambda ((:record A) 'record) (_ 'nope))>
   6. &trace: #<syntax (match 1 ((:record A) 'record) (_ 'nope))>
> (match 1
    ((:record (RTD A)) 'record)
    (_ 'nope))
nope
> 

I somewhat arbitrarily chose to make expand-time handles the default and
automatically wrap them in record-type-descriptor in the match
expression expansion, because I assumed most users will use
define-record-type and I didn't want adding record-type-descriptor to be
needed.  But I could also justify making descriptor expressions the
default and require adding record-type-descriptor for expand-time
handles.  Either way, the user is required to know if the "record type"
thing is an expand-time handle or run-time descriptor.  If record types
were always record type descriptors, this burden and abstraction
breakage would not exist.

-- 
: Derick
----------------------------------------------------------------


On Wed, 2009-09-02 at 20:44 -0700, Derick Eddington wrote:
> On Thu, 2009-09-03 at 06:15 +0300, Abdulaziz Ghuloum wrote:
> > On Sep 3, 2009, at 6:02 AM, Derick Eddington wrote:
> > 
> > >             ;; Will Clinger hates record-type-descriptor because it
> > >             ;; requires knowing whether the record type was defined  
> > > via the
> > >             ;; syntactic or procedural interface.
> > 
> > I don't understand this.
> > 
> > >                The below use is not
> > >             ;; portable, because it's unspecified which interface a
> > >             ;; particular implementation used to define &condition.
> > 
> > I don't think so.  &condition is a condition type as it says
> > in the report, and condition types can only be defined using
> > define-condition-type.  
> 
> But it's unspecified whether define-condition-type uses the syntactic or
> procedural record definition interface.
> 
> > So, (record-type-descriptor &condition)
> > has to return the rtd of &condition.
> 
> But record-type-descriptor is specified to require its argument to be a
> <record name> which is specified to be an expand-time handle or run-time
> value.  It's unspecified if a <record name> can be either or not.  The
> record type defined by define-condition-type might be a run-time value,
> while the <record name> defined by define-record-type and required by
> record-type-descriptor might be an expand-time handle, which leaves me
> not knowing if record-type-descriptor will work for &condition because
> &condition might be a run-time value.
> 
> Here's a better example of the issue:
> 
> > (library (L)
>     (export some-type)
>     (import (rnrs))
>     (define some-type
>       (make-record-type-descriptor 'some-type #F #F #F #F '#())))
> > (import (L))
> > (record-type-descriptor some-type)
> Unhandled exception
>  Condition components:
>    1. &who: record-type-descriptor
>    2. &message: "not a record type"
>    3. &syntax:
>        form: (record-type-descriptor some-type)
>        subform: #f
>    4. &trace: #<syntax (record-type-descriptor some-type)>
> > 
> 
> How/why are users supposed to know if some-type was defined via the
> procedural or syntactic interface?
> 
> > >               So I
> > >             ;; have to say, here's another example adding to my  
> > > dislike of
> > >             ;; record-type-descriptor.
> > 
> > Your last couple of dislikes were not very well founded. :-)
> 
> Hehehehe :)  I like flammable topics because they can reveal what
> actually burns.
> 


Reply via email to