Am Mi., 2. Nov. 2022 um 11:18 Uhr schrieb Marc Feeley <[email protected]>: > > > On Nov 2, 2022, at 3:10 AM, Marc Nieper-Wißkirchen > > <[email protected]> wrote: > > > > I want to point out that non-generative record-type definitions must > > not be garbage collected whether there are any references to the > > corresponding record-type descriptor (or records of this type) or not. > > > > The reason is that `make-record-type-descriptor' and similarly > > `make-record-descriptor' and `define-record-type' must detect the > > redefinition of a non-generative record type with incompatible shape. > > > > This has the consequence that in a long-running Scheme process (whose > > extent can exceed any Unix process and that can even be distributed), > > if a non-generative record type definition is modified in a source > > file, the Scheme system will complain unless the corresponding UID is > > changed as well. While this appears tedious, it is a good thing > > because it prevents silent errors when different parts of the process > > try to communicate through incompatible record types. > > I think this (the “must” detect the redefinition) would be too big of a > burden on the implementation. It is not even clear what scope the registry > must have (I would think it needs to be at the same level as a library > registry because some other programmer may be redefinining the record type > with no prior compilation of the original record type).
In the context of R6RS, which (only) has the notion of a top-level program to evaluate Scheme code, I think this is clear. In particular, pre-expansions of libraries must record the non-generative record-type definitions used during expansion as the existence of procedural macros implies that non-generative record types could have been defined. > In any case, there is a simpler approach, namely to create a hash of the > relevant parts of the record definition and to combine this hash with the > UID. That way, if the number of fields, the name of the fields, the UID, etc > change then the type will effectively be a different type. If we (or some extension) want to add read/write invariance, we will have to be careful: If we take the UID as the external (written) name of a record (which makes sense in the R6RS model), we must not have two incompatible record-type definitions with the same UID. Of course, we could use UID-HASH as the external name, but then we have to specify precisely how the HASH is derived (this may not be pretty; it reminds me of a C++ ABI). In any case, when we want to support the reading and writing of records, some solutions (and probably the simplest ) require that a record-type registry must be maintained anyway: > (define-record-type foo (nongenerative ...) ...) > (gc) > (read) <external representation of record type foo>
