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-experts/attachments/20240430/58811b11/attachment.htm>
More information about the amber-spec-experts
mailing list