Immutably updating objects Vladimir Nikishkin (31 Oct 2022 01:36 UTC)
Re: Immutably updating objects Arthur A. Gleckler (31 Oct 2022 03:57 UTC)
Re: Immutably updating objects Marc Nieper-Wißkirchen (31 Oct 2022 10:08 UTC)
Re: Immutably updating objects siiky (31 Oct 2022 10:18 UTC)
Re: Immutably updating objects Marc Nieper-Wißkirchen (31 Oct 2022 10:53 UTC)
Re: Immutably updating objects Vladimir Nikishkin (31 Oct 2022 12:54 UTC)
Re: Immutably updating objects Marc Nieper-Wißkirchen (31 Oct 2022 13:09 UTC)
Re: Immutably updating objects Vladimir Nikishkin (03 Nov 2022 02:12 UTC)
Re: Immutably updating objects Marc Nieper-Wißkirchen (03 Nov 2022 07:13 UTC)
Re: Immutably updating objects Vladimir Nikishkin (03 Nov 2022 08:56 UTC)
Re: Immutably updating objects Marc Nieper-Wißkirchen (03 Nov 2022 13:17 UTC)

Re: Immutably updating objects Marc Nieper-Wißkirchen 03 Nov 2022 13:17 UTC

Am Do., 3. Nov. 2022 um 09:56 Uhr schrieb Vladimir Nikishkin
<xxxxxx@gmail.com>:
>
> >I am looking forward to your response,
>
> I need to think more about it, thank you.
>
> >So if you want class B to be a child of class A, the set of values
> >class A models has to be extended (and its invariant thus relaxed).
>
> Well, but there is a difference between "what a class can model", and
> "what an object can model".
> I guess, if objects are immutable, and a "pure update" creates a new
> object, then I guess what you are saying is correct.
>
> Inheritance usually does not only mean "subsetting", it is also "extension".
> Maybe inheriting a one-dimensional vector to obtain a two-dimensional is
> not a very good practice, but I can see why this may be useful.

"Inheritance" is semantically implemented in the Scheme record systems
through the type predicates.  So we have two predicates, `a?' and `b?'
such that `b?' is true on an object if `a?' is true on an object (but
not necessarily vice versa).  I think it boils down to what your
contract (with users of your code) about the predicate `a?' is.  If a
user writes a procedure of the form

(define frobnicate
  (lambda (r)
    (assert (a? r))
    ...))

and assumes a particular invariant of the contract about `a?', the
code would become incorrect if an object of type `b?' can be passed
that does not fulfill the contract.

>
> On Thu, 3 Nov 2022 at 15:13, Marc Nieper-Wißkirchen
> <xxxxxx@gmail.com> wrote:
> >
> > Am Do., 3. Nov. 2022 um 03:12 Uhr schrieb Vladimir Nikishkin
> > <xxxxxx@gmail.com>:
> > >
> > > >The values R, X_0, Y_0 are meant to be constants outside the record, are they?
> > >
> > > Yes. The record describes a set of points around some point fixed at
> > > record creation time.
> > >
> > > >Could you redescribe your model, e.g. withsome Scheme code and with less "imagination"? :)
> > >
> > > Not sure I can do that with Scheme code.
> > > But what I am talking about is essentially "protected" in C++.
> > > When seen as an instance of the parent class A, the points X and Y
> > > obey an invariant.
> > > However, when class A is a parent class of some child class B, this
> > > rule becomes:
> > > X and Y obey an invariant, which is nevertheless different for each
> > > value of some Z defined in B, and this Z might be mutable.
> > > So when Z is mutated using set-Z! in the child class B, it has to
> > > change the invariant, which is impossible using only class A's public
> > > interface.
> > > (And also adjust X and Y, but that is doable using A's public methods.)
> >
> > Thank you for your explanation.
> >
> > If class A is semantically defined so that X and Y obey the original
> > invariant, then class B is semantically not a child of class A (if
> > class A models white mammals and class B models black cats, class B
> > cannot be semantically a child of class A).
> >
> > So if you want class B to be a child of class A, the set of values
> > class A models has to be extended (and its invariant thus relaxed).
> >
> > This is nothing particularly about Scheme, just about what is usually
> > understood by a type and a subtype (and applies equally to classical
> > OOP languages).
> >
> > So what you can do is the following example:
> >
> > (define-record-type base
> >   (fields x y invariant)
> >   (protocol
> >     (lambda (n)
> >       (lambda (x y invariant?)
> >         (assert (procedure? invariant?))
> >         (assert (invariant? x y))
> >         (p x y invariant)))))
> >
> > (define-record-type simple-child
> >   (parent base)
> >   (protocol
> >     (lambda (n)
> >       (lambda (x y)
> >         (define invariant?
> >           (lambda (x y)
> >             (<= (+ (* x x) (* y y)) *radius*)))
> >         ((n x y invariant?))))))
> >
> > (define-record-type complicated-child
> >   (parent base)
> >   (protocol
> >     (lambda (n)
> >       (lambda (x y z)
> >         (define invariant? ...)
> >         ...))))
> >
> > Note that you don't have to export the base class from your module.
> > This allows you to somehow model the "protected" specifier of C++.
> >
> > I am looking forward to your response,
> >
> > Marc
> >
> > > On Mon, 31 Oct 2022 at 21:09, Marc Nieper-Wißkirchen
> > > <xxxxxx@gmail.com> wrote:
> > > >
> > > > Am Mo., 31. Okt. 2022 um 13:54 Uhr schrieb Vladimir Nikishkin
> > > > <xxxxxx@gmail.com>:
> > > > >
> > > > > >An updater of a child record type should not have to deal directly
> > > > > >with updating the fields of its parent (because would breach an
> > > > > >abstraction barrier); instead, an updater of a child record type
> > > > > >should call a corresponding updater for a parent record type.
> > > > >
> > > > > I think this might not be possible in the general case. Or, rather,
> > > > > it might depend on whether we want "non-virtual" or "virtual"
> > > > > inheritance in r7rs-large.
> > > > > (Not sure "virtual" is the correct term.)
> > > >
> > > > We must be careful with these terms coming from a classical OOP model
> > > > like C++ or Java.  As I explained in [1], the record system of Scheme
> > > > is much simpler and does not implement OOP (but can be used to
> > > > implement an OOP layer).
> > > >
> > > > > A (very contrived) counterexample would be a struct which describes a
> > > > > point on a plane
> > > > > which has coordinates X and Y, but cannot leave a disc of radius R
> > > > > with the center in some point X_0, Y_0.
> > > > > There might be some algorithms which work with such a point.
> > > > > R, X_0, Y_0 are set at construction only, X and Y have set-X! and set-Y!
> > > > > Imagine drawing the bottom of a cup standing on a table.
> > > >
> > > > The values R, X_0, Y_0 are meant to be constants outside the record, are they?
> > > >
> > > > >
> > > > > Now we want to extend this point to work on a certain Z(X,Y) curve,
> > > > > parameterised by the length of the segment ɑ.
> > > > > Imagine lifting a cup off the table and placing it at some other point
> > > > > on the table,
> > > > > the bottom of the cup is the original struct.
> > > > >
> > > > > We want the algorithms to keep working for the "bottom of the cup",
> > > > > and the X²+Y² <R²  to be
> > > > > preserved. But in order to describe this case, the method set-ɑ! of
> > > > > the child object would
> > > > > necessarily have to mutate X_0, Y_0, X, Y (but not R).
> > > > >
> > > > > I understand that this example is very contrived, but I really suspect
> > > > > that restricting a child's access to
> > > > > parent's protected fields is unnecessarily limited.
> > > >
> > > > I fear I don't understand your example in detail so that I could give
> > > > a satisfactory answer.  Could you redescribe your model, e.g. with
> > > > some Scheme code and with less "imagination"? :)
> > > >
> > > > --
> > > >
> > > > [1] https://srfi-email.schemers.org/srfi-237/msg/20934836/
> > >
> > >
> > >
> > > --
> > > Yours sincerely, Vladimir Nikishkin
> > > (Sent from GMail web interface.)
>
>
>
> --
> Yours sincerely, Vladimir Nikishkin
> (Sent from GMail web interface.)