Truly unifying R6RS and R7RS Daphne Preston-Kendal (04 Oct 2022 18:22 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (04 Oct 2022 19:16 UTC)
Re: Truly unifying R6RS and R7RS John Cowan (06 Oct 2022 20:30 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (06 Oct 2022 21:11 UTC)
Re: Truly unifying R6RS and R7RS John Cowan (07 Oct 2022 01:33 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (07 Oct 2022 08:20 UTC)
Re: Truly unifying R6RS and R7RS Arthur A. Gleckler (07 Oct 2022 18:22 UTC)
Re: Truly unifying R6RS and R7RS John Cowan (07 Oct 2022 22:02 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (08 Oct 2022 10:37 UTC)
Re: Truly unifying R6RS and R7RS José Bollo (27 Oct 2022 07:30 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (27 Oct 2022 08:00 UTC)
Re: Truly unifying R6RS and R7RS José Bollo (01 Nov 2022 14:22 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (01 Nov 2022 14:34 UTC)
Re: Truly unifying R6RS and R7RS José Bollo (03 Nov 2022 08:42 UTC)
(missing)
Fwd: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (03 Nov 2022 13:18 UTC)
Re: Truly unifying R6RS and R7RS José Bollo (26 Nov 2022 10:02 UTC)
Re: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen (26 Nov 2022 17:26 UTC)

Fwd: Truly unifying R6RS and R7RS Marc Nieper-Wißkirchen 03 Nov 2022 13:17 UTC

Forgot to include the list.

---------- Forwarded message ---------
Von: Marc Nieper-Wißkirchen <xxxxxx@gmail.com>
Date: Do., 3. Nov. 2022 um 13:54 Uhr
Subject: Re: Truly unifying R6RS and R7RS
To: José Bollo <xxxxxx@nonadev.net>

Am Do., 3. Nov. 2022 um 09:42 Uhr schrieb José Bollo <xxxxxx@nonadev.net>:
>
> Le Tue, 1 Nov 2022 15:33:44 +0100,
> Marc Nieper-Wißkirchen <xxxxxx@gmail.com> a écrit :
>
> Hello,
>
> > Am Di., 1. Nov. 2022 um 15:22 Uhr schrieb José Bollo
> > <xxxxxx@nonadev.net>:
> > >
> > > Le Thu, 27 Oct 2022 10:00:17 +0200,
> > > Marc Nieper-Wißkirchen <xxxxxx@gmail.com> a écrit :
> > >
> > > Hi,
> > >
> > > More thoughts to share. Trying to be short.
> > >
> > > 1. OO langages mostly allow multiple constructors -with different
> > > signatures- (many of it -C++, Java- use unique name and overloading,
> > > shit on it -just may silly opinion-) Anyway it is used so it is of
> > > interest. Need example?
> > >
> > > (define-record-type <sbuf> (!sbuf! len vec) sbuf?
> > >    (len sbuf-length sbuf-set-length!)
> > >    (vec sbuf-buffer))
> > >
> > > (define (make-sbuf-with-capacity capacity)
> > >   (!sbuf! 0 (make-vector capacity #\null)))
> > >
> > > (define (make-sbuf-from-string string)
> > >   (!sbuf! (string-length string) (string->vector string)))
> > >
> > > My understanding is that protocol of r6rs doesn't give any facility
> > > for that case. It is intended for inheritance only but restrict its
> > > usage to a single signature (but okay we can use case-lambda,
> > > perhaps).
> >
> > The procedural layer of R6RS allows you to define as many constructors
> > as you want; only the syntactic layer is limited (but not in
> > principle).
> >
> > The newest draft of SRFI 237 now included "define-record-name", which
> > is a syntactic facility to define new constructors without defining
> > new record types.
> >
> > > 2. define-record-type is not OO. The issues solved by protocol
> > > remain for methods that are not constructors and are not solved. So
> > > the need is for constructor only.
> >
> > What do you mean by "are not solved"?
>
> I mean "calling precursor method in a redefined method in inheriter
> class", as offered by some OO languages. Maybe still not clear. If in a
> class B inheriting A we redefine the method foo but to implement it, we
> need to invoke the origin method foo of A.
>
> It is really not a scheme paradigm but it is near in its mechanism to
> the problem we are debating.

The scope of the record facility described in SRFI 237 is limited on
purpose.  It does not define a full-fledged OOP framework.  But it
offers building blocks so that such a full-fledged OOP can be
implemented on top of it without making compromises with respect to
efficiency.

You may wonder why SRFI 237 talks about constructors and somehow about
inheriting from constructors but not about methods and derived
methods.  The reason is that constructors are special because when a
constructor is called, a record is not yet constructed, and
outsourcing to a wrapper procedure is not possible (at least not
without efficiency losses) because records can have immutable fields.

(Related to this is that C++ constructors have the ": ..." syntax to
initialize fields.  This syntax does not occur with C++ methods.)

> > > I imagine a procedure that wraps children fields to provide a parent
> > > constructor. It could solve. Let use R6RS's abstract example (p18)
> > > with SRFI-136 formalism and with some functions foo, bar1 and bar2.
> > >
> > > (define-record-type <parent> !parent! parent?
> > >    (v1 v1) (v2 v2) (v3 v3))
> > >
> > > (define-record-type (<child> <parent>) !child! child?
> > >    (x1 x1) (x2 x2) (x3 x3) (x4 x4))
> > >
> > > (define (make-parent v1 v2 . build)
> > >    (let ((make (if (null? build) !parent! (car build))))
> > >       (make v1 v2 (foo v1 v2))))
> > >
> > > (define (make-child x1 x2 x3 v1)
> > >    (let ((x4 (bar1 x1 x2 x3 v1))
> > >          (v2 (bar2 x1 x2 x3 v1)))
> > >       (make-parent v1 v2 (lambda (v1 v2 v3)
> > >             (!child! v1 v2 v3 x1 x2 x3 x4)))))
> > >
> > > Works but it is not perfect. It has to be forged by the programmer
> > > and included in the design, it does not comes for free. What comes
> > > for free is the constructor !child!.
> > >
> > > Instead of (lambda (v1 v2 v3) (!child! v1 v2 v3 x1 x2 x3 x4)), a
> > > facility function could exist:
> > >  ((record-type-wrap-creator-for-parent <child>) x1 x2 x3 x4)
> > >
> > > It is very similar in the approach to protocol. Maybe more
> > > flexible.
> >
> > If I understand your code correctly, it seems that the child record
> > has to know about the fields of the parent record type, which the R6RS
> > approach avoids - and allows decoupling implementations.
>
> Yep and that is why I proposed the function with that very long name:
> record-type-wrap-creator-for-parent. That function, given the type name
> automatically returns the correct lambda.
>
> Its signature is
>
>   RECORD-TYPE
>        --> proper fields of the childs
>               --> parent fields of parent
>                       --> created record instance
>
> It could also be that signature
>
>   RECORD-TYPE and proper fields of the childs
>        --> parent fields of parent
>               --> created record instance
>
> But a generic function could do the job:
>
>  (lambda (child-constructor)
>      (lambda child-args
>          (lambda parent-args
>               (apply child-constructor
>                      (concat parent-args child-args)))))
>
> Or something similar. Having a specialized function could help to check
> the count of arguments.

Where do the parent args come from (or where is your `make-parent' in
the above description)?  It seems to me that what you propose is at
least not simpler than what's in R6RS/SRFI 237.  For the R6RS
interface, I know that it has been intensively tested and that any
runtime overhead is kept minimal.  This is not so clear to me
regarding your proposal.

> > Anyway, please check `define-record-name' and see whether it solves
> > your use case.
>
> I'm not sure to understand it clearly. It looks like a syntactic sugar,
> not like a real behaviour.

It is insofar syntactic sugar as you can achieve the same with the
procedural interface.  But it means that you can forget about the
procedural layer if you are interested in defining more than one
constructor for one record-type.

> > > And, also, I'm very sorry but I am very happy with the generativity
> > > of define-record-type in R7RS. It is clear and regular with other
> > > parts of the language.
> >
> > You don't have to be sorry. :) Where are you using generative
> > record-type definitions in practice?
>
> Well, in my usage, it doesn't care if it is generative or not. Both are
> achieving the same behaviour.

So you are not using generativity.

Non-generativity is what people know from most other languages.  In C,
for example, structs are compatible whenever they have compatible
fields, no matter in which and in how many translation units they are
defined (here, conceptually, the UID is derived from the shape).

> I believe that turning generative type to non generative type can be
> achieved using a correct decomposition in libraries. But I may be wrong,
> I have no experience in providing any libraries of interest.

This works if your record types are only defined in the top level of a
library, and your library is only loaded once.

> Conversely, you started a thread "Perpetuity of non-generative record
> type definitions". Between the lines it indicates that being
> non-generative might be a nightmare to implement.

No, it's not a nightmare to implement them.

>
> Best regards
> José
>
> > Best wishes,
> >
> > Marc
>