Perpetuity of non-generative record type definitions
Marc Nieper-WiÃkirchen 02 Nov 2022 07:10 UTC
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.
In some sense, the internal record-type registry of the Scheme process
keeps a list of already used (burnt) UIDs, enforcing that UIDs are
truly unique as far as the record-type facility is concerned.
It should be noted, though, that one can define a procedure like
(define reduce-memory!
(lambda ()
(do ([i 0 (fx+i 1)])
((fx=? i 10000))
(make-record-type-descriptor 'record #f #f (gensym) #f #f '#()))))
which allocates wasted memory forever (relative to the lifetime of the
Scheme process).
This, however, is not singular; it also works with other Scheme
extensions. Replace the make-record-type-descriptor line with, say,
(putprop (gensym) (gensym) (gensym))
or with
(eval `(define ,(gensym) ,(gensym)) (interaction-environment))
Marc