Constructors, excessive consing, R7RS Large Daphne Preston-Kendal (21 Nov 2024 20:34 UTC)
Re: Constructors, excessive consing, R7RS Large Arthur A. Gleckler (21 Nov 2024 20:42 UTC)
Re: Constructors, excessive consing, R7RS Large Marc Nieper-Wißkirchen (21 Nov 2024 21:29 UTC)
Re: Constructors, excessive consing, R7RS Large Marc Nieper-Wißkirchen (22 Nov 2024 08:08 UTC)

Re: Constructors, excessive consing, R7RS Large Marc Nieper-Wißkirchen 22 Nov 2024 08:08 UTC

Chez Scheme's optimiser is not able to remove the temporary heap
allocation in the following example, although it is able to inline the
procedures.

(define (make-book name)
  (assert (string? name))
  (vector name (string-length name)))
(define (make-color-book name colour)
  (let ((book (make-book name)))
    (vector (vector-ref book 0) (vector-ref book 1) colour)))
(make-color-book "SICP" 'blue)

The average Scheme implementation will likely do even fewer optimisations.

Am Do., 21. Nov. 2024 um 22:28 Uhr schrieb Marc Nieper-Wißkirchen
<xxxxxx@gmail.com>:
>
> Am Do., 21. Nov. 2024 um 21:34 Uhr schrieb Daphne Preston-Kendal
> <xxxxxx@nonceword.org>:
> >
> > I hope Arthur doesn’t mind me answering publically a comment he sent privately, since I think it sums up what may be some common responses to this proposal:
> >
> > > I have just one non-editor comment: Sometimes, I define several record types in a hierarchy, and they're meant to be used together, i.e. they're part of the same program.  In that case, I like having the ability to define a constructor for a subtype that includes all the fields of the supertype.  That reduces consing.  I hope that  R7RS Large won't lose that capability.
> >
> > 1. You can still do this, you just have to explicitly define a constructor procedure which takes the arguments you want; I expect that will be the most common way constructors of subtypes are used in practice, and the one defined by define-record-type itself is just a primitive used to build a slightly more palatable interface.
> >
> > 2. I considered the consing problem but also think that any compiler with a halfway decent inliner should be able to eliminate it in the common case when the first argument to the auto-defined constructor for a subtype is a call to any simple constructor for its supertype. Perhaps I should provide a third sample implementation where you can see that, for example, Chez’s cp0 is already basically capable of this (and that this can be seen with the expand/optimize procedure). The R6RS-based implementation doesn’t do this very well because it has to run circles around the R6RS record system to make it work the way it wants.
>
> I was less concerned about Chez, and more about less optimizing
> implementations (something as basic as records should be implementable
> efficiently without too much effort).  Inlining is only the first
> step; then, the implementation has to recognise that the creation of a
> temporary record can be elided. For the auto-generated constructors,
> this will likely be the case, but if one promise of this SRFI is
> encapsulation and abstraction, the general case of a constructor that
> does non-trivial work (e.g. by checking arguments or calculating field
> values) should be equally considered (an example is given in the
> SRFI).
>
> But even if this problem is smaller than it may appear, abstract
> record types would still have to expose a constructor that should not
> actually be used as a constructor, which is, at least, inelegant.
>
> > 3. I have no idea whether this SRFI is destined for R7RS Large. I consider it an experiment in trying to bring R7RS small records closer in terms of features to R6RS records.
>
> Improving the R7RS small record system is certainly a good idea, but
> it should be done in a way that makes interoperability with the R6RS
> system trivial. In the case of the features of SRFI 256, this would
> mean adopting the "protocol" protocol.  Is there a reason why this
> couldn't be possible?