(Previous discussion continued)
Re: propositions, oppositions, and some minor details Andre van Tonder 13 Sep 2004 19:00 UTC

Re: propositions, oppositions, and some minor details Andre van Tonder 13 Sep 2004 19:00 UTC

Hi Taylor, let me try to answer your comments:

On Sun, 12 Sep 2004 xxxxxx@autodrip.bloodandcoffee.net wrote:

> First, my thoughts on the matter of syntactic details.  With respect to
> compatibility with SRFI 9, I think it would just be easier if the
> predicate were mandatory.  I don't see much of a reason to omit it,
> and, by mandating it, it removes ambiguity: it clearly delimits the
> type name & the constructor specifier from the fields.  Also, I don't
> like the token for specifying mutability.  I think it would be better
> to have a <field spec> nonterminal where the token for mutability is
> _not_ a symbol; I think it would also be a bit more consistent to allow
> a mutable field with an accessor but no separate modifier defined.
> This replacement <field spec> nonterminal would fix both problems,
> given some <mutability token>, e.g. #T/#F:
>
>  <field spec> ->
>      (<field label> [<accessor name>] [<mutability token>])
>    | (<field label> <accessor name> <modifier name>)

How would you like the following (also proposed by Alex Shinn):  Keep the
SRFI-9 syntax mostly and just use #f for omitted elements, along with a
couple of additional shortcuts:

  (define-record-type node (make-node left right) node?
                  (left  node-left  node-left-set!)
                  (right node-right node-right-set!))

Examples of variations:

  (define-record-type node make-node #f (left  node-left  #f)
                                        (right node-right #f))

    --> no predicate, default constructor arguments,
        both fields mutable but no setters defined

  (define-record-type node make-node #f (left #f #f) (right #f #f))

    --> as above, fields are mutable, but no getters or setters defined

  (define-record-type node make-node #f (left #f) (right #f))

    --> as above, but both fields immutable

  (define-record-type node make-node #f left right)

   --> shortcut for previous

  (define-record-type node #f #f left right)

   --> bare minimum if we have fields

  (define-record-type node make-node)
  (define-record-type node)

   --> adiitional shortcuts suggested by Felix if we have no fields

Mutability would depend, as in SRFI-9, on whether field clause is a two or
three element list (or special case of atom as above).

The disadvantage would be all those little spiders walking across the
screen when we want to leave things out, but maybe this design, because of
its backward-compatibility, will please more people (in addition to being
slightly more flexible) than my original.

> The last syntactic detail that bothers me is the use of record types'
> constructors in the pattern matching.  It would seem more sensical to
> me to use the record type names themselves, not their constructors;
> this would also solve the problem that required identifier macros --
> which I am loathe to consider -- when defining the constructors so that
> they could be used as regular variable bindings, bound to procedures,
> as the specification specifies: they would no longer need syntactic
> information used in pattern matching.

In accordance with the apparent majority opinion, I am pretty much decided
on splitting pattern matching off (editors and the gods of time
management willing), so this discussion should perhaps be left for then.
I will just mention that with a more powerful macro system, one can keep
a compile-time registry, obviating the need to bind constructor names as
identifier macros.  So it becomes a matter of taste whether one wants
match expressions to look like the corresponding constructors or perhaps
more like external representations or whatever.  As you no doubt know,
both styles of matchers exist for Scheme.

> I also have a somewhat deeper semantic question: can SRFI 57 be used to
> define subtypes of record types defined with SRFI 9?  My suggestion: an
> emphatic *YES*.

I would agree.

> I am also *vehemently* opposed to the completely unrestricted operator
> of reflection RECORD->SEXP.  Reflection should either be completely
> expurgated -- as I'd prefer --, or, if you intend to include any at all
> in this SRFI, highly controlled by whomever defined the record type.
> For example, Scheme48 has a simple, controlled mechanism for disclosing
> the components of particular record types, though mostly for printing
> unreadable objects.  I don't want to clutter this email describing it,
> however, unless requested; request if you want me to.

Thanks, yes, I looked it up.  I am not really happy either with
record->sexp; on the other hand it may be better than nothing - something
like it could be rather useful not just for generic printing but also
other generic operations such as debugging (as Felix mentioned), generic
unification algorithms over records, etc.  Are you worried about data
hiding?  Of course the other side of the generic coin concerns generic
construction of record values (e.g. reading), which I am reluctant to
tackle in this SRFI because of its difficulty.  I am open to more
suggestions.

> A smaller issue that I brought up on c.l.s seemed to have been left
> unnoticed: record type equivalence seems to be based on name, not on
> identity of the record type.  I believe this could be fixed by defining
> an extra variable when invoking DEFINE-RECORD for a token identifying
> the newly defined record type, and comparing against this, instead of
> symbolic names, in BUILD-MAKER.

I prefer the simplicity of name equivalence.  I know that with
this interpretation, redefining a record type may break code that depends
on the prior definition, but so may redefining a procedure or macro in
standard Scheme.

> Regarding implementations, it is obviously not tractable for many
> Scheme implementations to implement DEFINE-RECORD as a syntax-rules
> macro of such extreme proportions; although I find it amazing that you
> wrote such a macro, I don't think it's practical, _especially_ not for
> implementations that implement syntax-rules by translating the
> expression into Scheme, compiling the Scheme, and then running that --
> for _every_ use of syntax-rules.  I believe it would be a good idea to
> provide an alternative implementation of DEFINE-RECORD in terms of even
> a non-standard macro system, such as the fairly widely implemented
> explicit renaming.*  It would also be undoubtedly easier to maintain as
> the SRFI evolves than this gargantuan set of syntax-rules macros.

I agree.  I actually started working on an alternative implementation
in syntax-case but stopped for lack of time (as well as disgust at the
non-uniformity of the available implementations, different methods of
phase control, etc.)

> Finally, it would also be good if an implementation were provided -- be
> it in syntax-rules or explicit renaming or anything, as long as it can
> be shown that it works -- that based records on the low-level record
> interface used internally by SRFI 9's implementation, because that is
> what most 'real' implementations will likely be based on.

I agree it could be good, but this would be somewhat on the back-burner as
far as I'm concerned, I'm afraid.  Closures can be rather efficient,
especially once you start mixing pattern matching into the equation.

Regards
Andre