Derived record creation and Data Oriented programming

Brian Goetz brian.goetz at oracle.com
Tue Apr 30 13:32:35 UTC 2024


Interesting idea.  Of the two sides, allowing explicit *constructor* 
calls is significantly more practical (`yield` has control flow 
consequences understood by the language, and obviously means "yield this 
value from the current expression", whereas doing a random pattern match 
with `this` as a match candidate is not remotely clear that you intend 
to override the deconstruction.)

But, let's back up a second: what do we gain from this?  Let's say we 
have two records with similar states:

     record A(int x, int y, int z) { }
     record B(int x, int y, int z) { }

A a = ...
B b = a with { yield new B(x, y, z); }

I don't see how this is more clear than:

B b = switch (a) {
           case A(var x, var y, var z) -> new B(x, y, z);
       };

(or an imperative match, if we have one.)  In fact, it seems less clear, 
since it is not really a "with" anything.  It's using `with` as a short 
form of "shred to components", which is not what `with` is intended to 
convey.

So let's back up: what problem are we trying to solve here?

On 4/30/2024 9:22 AM, Remi Forax wrote:
> Hello,
> they have been several messages on amber-dev about the compatibility of the derived record creation.
>
> I think part of the issue reported is that with the proposed syntax, the call to the desconstructor and the canonical constructor is implicit.
>
> Let's take an example
>
>    record Point(int x, int y) {}
>
>    var point = new Point(2, 3);
>
>
> In fact,
>    var point2 = point with { x = y; };
>
> is a shortcut for:
>
>    var point2 = point with {
>      Point(int x, int y) = this;  // i.e. int x = this.x(); int y = this.y();
>      x = y;
>      yield new Point(x, y);
>    };
>
> One problem with the current syntax is that because the call to the [de]constructors is implicit. I think we shoud allow users to write the implicit calls if they want.
>
> I wonder if
> - we should not allow yield to be used so the compiler adds yield automatically only if there is no yield ?
> - we should in the future when deconstructors are introduced, allow users to call a deconstructor explicitly and only provide one if not explicitly written ?
>
> Being able to write the calls explicitly is important because it's a way to detect if the record has been modified without the proper constructor/destructor has been written to be backward compatible (Like in a switch, a record pattern detects when a record component is added while a type pattern does not).
>
> Being able to call a the deconstructor explicitly also have the advantage to avoid to declare a variable/calls the accessor if not needed.
> By example
>    var point2 = point with {
>      Point(_, var y) = this;
>      x = y;
>    };
>
> regards,
> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20240430/58811b11/attachment.htm>


More information about the amber-spec-observers mailing list