Generative and nongenerative record types Marc Nieper-Wißkirchen (30 Oct 2022 09:09 UTC)
Re: Generative and nongenerative record types John Cowan (30 Oct 2022 16:37 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (30 Oct 2022 16:57 UTC)
Re: Generative and nongenerative record types John Cowan (30 Oct 2022 22:20 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (31 Oct 2022 09:12 UTC)
Re: Generative and nongenerative record types Marc Feeley (31 Oct 2022 12:00 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (31 Oct 2022 12:37 UTC)
Re: Generative and nongenerative record types Marc Feeley (31 Oct 2022 13:21 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (02 Nov 2022 13:09 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (02 Nov 2022 14:57 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (03 Nov 2022 19:20 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (08 Nov 2022 16:23 UTC)
Re: Generative and nongenerative record types Daphne Preston-Kendal (08 Nov 2022 16:24 UTC)
Re: Generative and nongenerative record types Marc Nieper-Wißkirchen (08 Nov 2022 16:29 UTC)

Re: Generative and nongenerative record types Marc Nieper-Wißkirchen 02 Nov 2022 13:09 UTC

Am Mo., 31. Okt. 2022 um 14:21 Uhr schrieb Marc Feeley (via srfi-237
list) <xxxxxx@srfi.schemers.org>:
>
> > On Oct 31, 2022, at 8:36 AM, Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:
> >
> > Am Mo., 31. Okt. 2022 um 13:00 Uhr schrieb Marc Feeley
> > <xxxxxx@iro.umontreal.ca>:
> >
> >> However I’m not arguing that nongenerative record definitions should be the default even though in the Gambit codebase most if not all of the record type definitions are nongenerative.  Due to the presence of a UID the nongenerative record definitions are a bit more verbose and visually inelegant than generative ones.  Note that I think R6RS has a design error in allowing nongenerative record definitions without a UID (it just slightly shifts the meaning of type instantiation and will not work in the above use cases and most people will not fully grasp the meaning of a UID-less nongenerative record type definition).
> >
> > A nongenerative clause without a UID has a defined meaning, sitting in
> > between generative record types and non-generative ones with a UID:
> > In the case of "global" library definitions, It means that a record
> > type is generated per visit of a library, not one per instance of a
> > library (as would be a generative record-type) and not one per big
> > bang (as would be a non-generative record-type with a UID).
> >
> > I think this part of R6RS is okay; the actual problem is the library
> > system of R6RS is not strict about the number of visits to a library,
> > presumably so that, at that time, the module system of MzScheme was a
> > faithful implementation.  (Notable, Racket does not allow a
> > nongenerative clause without a UID.)  As we have agreed upon implicit
> > phasing, we can remove this problematic part of R6RS (which makes it
> > hard to write portable programs despite that this was a design goal of
> > R6RS), by enforcing that libraries must only be expanded once per
> > program run.  (This still needs UIDs in portable code for
> > communication between different instances of the program if
> > portability is required.)  In a sense, one can think of each visit
> > having its own UID, and this being prepended to auto-generated UIDs of
> > record-types.
> >
>
> As I say “most people will not fully grasp the meaning of a UID-less nongenerative record type definition”.  But thanks for pointing out that it is not even consistent between implementations and Racket has dropped UID-less nongenerative records.

I would say it is consistent within the limited area that R6RS
actually defines.  (I don't know whether Racket has dropped UID-less
nongenerative records or whether they were never implemented.)

> When you say “we can remove this problematic part of R6RS” you mean remove UID-less nongenerative records?  You have my vote for that.

I meant the underspecification of phasing and the number of visits and
instantiations of a library.  For R7RS Small, such underspecification
would have made total sense, but not for R6RS, whose goal is
different.  I can only guess, but it seems to be that this
underspecification has its root in the wish to make the module system
of R6RS compatible with both MzScheme's and Chez's. In the end, you
get the worst of both worlds: For example, for portable code, you have
to write explicit phases, but you only get their disadvantages but
none of their advantages.

But I see why you say that UID-less nongenerative records are also
problematic.  For quick-and-dirty programming and some backward
compatibility, I like to leave them in the language (at least until I
have told Emacs to generate UIDs for me), but at least we can
encourage implementations to raise a continuable exception of type
&warning whenever they expand a UID-less nongenerative record type.

Would that be an acceptable compromise for you?

> > If we can't agree to change the default from generative to
> > non-generative, what we can do instead is to allow the non-generative
> > clause to be of the form "(nongenerative #f)" and to advise
> > implementations to issue a warning when it sees a record type without
> > a non-generative clause of either form.
>
> Double negatives are not great.  Moreover (nongenerative #f) is too easy to confuse with (nongenerative) because #f often means “not supplied” in many APIs.

Fair enough, so maybe "(generative)" is a better way to make it explicit.

>
> By the way I wasn’t saying I’m against making the nongenerative case the “default”.  But what does “default” mean here if a UID needs to be supplied with the clause? “Default” only makes sense if the UID-less variant is supported, and I think that would be a blunder.  Isn’t the real issue one of educating programmers rather than syntax?

Agreed.

So, instead of what I initially wrote in this thread, every
record-type definition (R6RS-style) should either have a
(nongenerative <uid>) or a (generative) clause.