New candidate JEP: 468: Derived Record Creation (Preview)

Attila Kelemen attila.kelemen85 at gmail.com
Sat Apr 20 17:35:34 UTC 2024


The compilation strategy doesn't matter. I'm just considering what the JEP
implies (at least given my understanding) about the meaning of the code.
What you are saying is relevant for binary compatibility (which I don't
assume is broken). My problem is that when the example code is recompiled
against the new version of `MyRecord`, then according to the JLS
`MyProperty.z` shadows the `int z = 26;` (the JEP explicitly states this).
So, the compiler must produce different code for the two variants of the
record (otherwise it breaks the spec written in the JEP).

Remi Forax <forax at univ-mlv.fr> ezt írta (időpont: 2024. ápr. 20., Szo,
19:30):

>
>
> ------------------------------
>
> *From: *"attila kelemen85" <attila.kelemen85 at gmail.com>
> *To: *"amber-dev" <amber-dev at openjdk.org>
> *Cc: *"Gavin Bierman" <gavin.bierman at oracle.com>, "jdk-dev" <
> jdk-dev at openjdk.org>
> *Sent: *Saturday, April 20, 2024 5:49:22 PM
> *Subject: *Re: New candidate JEP: 468: Derived Record Creation (Preview)
>
> I have a backward compatibility concern about this JEP. Consider that I
> have the following record:
> `record MyRecord(int x, int y) { }`
>
> One day I realize that I need that 3rd property which I want to add in a
> backward compatible way, which I will do the following way:
>
> ```
> record MyRecord(int x, int y, int z) {
>     public MyRecord(int x, int y) {
>         this(x, y, 0);
>     }
> }
> ```
>
> As far as I understand, this will still remain binary compatible. However,
> if I didn't miss anything, then this JEP makes it non-source compatible,
> because someone might wrote the following code:
>
> ```
> var obj1 = new MyRecord(1, 2);
> int z = 26;
> var obj2 = obj1 with { y = z; }
> ```
>
> If this code is compiled again, then it will compile without error, but
> while in the first version `obj2.y == 26`, now `obj2.y == 0`. This seems
> rather nasty to me because I was once bitten by this in Gradle (I can't
> recall if it was Groovy or Kotlin, but it doesn't really matter), where
> this is a threat, and you have to be very careful adding a new property in
> plugin extensions with a too generic name. Even though Gradle scripts are
> far less prone to this, since those scripts are usually a lot less
> complicated than normal code.
>
> I saw in the JEP that on the left hand side of the assignment this issue
> can't happen, but as far as I can see the above problem is not prevented.
>
> My proposal would be to, instead of shadowing variables, raise a compile
> time error when the property name would shadow another variable. Though
> that still leaves the above example backward incompatible, but at least I
> would be notified of it by the compiler, instead of the compiler silently
> creating a bug.
>
> Another solution would be that the shadowing is done in the opposite
> order, and the `int z = 26;` shadows the record property (with a potential
> warning). In this case it would be even source compatible, if I didn't miss
> something.
>
> Attila
>
>
> Hello, i think you are pre-supposing a specific compiler translation
> strategy, but it can be compiled like this:
>
> MyRecord obj1 = new MyRecord(1, 2);
> int z = 26;
>
> Object carrier = indy(r);  // create a carrier object by calling all the
> accessors
>                                        // so the side effects are done
> before calling the block
> int y = z;
> MyRecord obj2 = indy(carrier, /*y:*/ y);  // create an instance of
> MyRecord using 'y' and the values in the carrier
>
> With the carrier instances working like
> https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/runtime/Carriers.java
>
> regards,
> Rémi
>
>
> Mark Reinhold <mark.reinhold at oracle.com> ezt írta (időpont: 2024. febr.
> 28., Sze, 21:04):
>
>> https://openjdk.org/jeps/468
>>
>>   Summary: Enhance the Java language with derived creation for
>>   records. Records are immutable objects, so developers frequently create
>>   new records from old records to model new data. Derived creation
>>   streamlines code by deriving a new record from an existing record,
>>   specifying only the components that are different. This is a preview
>>   language feature.
>>
>> - Mark
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jdk-dev/attachments/20240420/e1302575/attachment-0001.htm>


More information about the jdk-dev mailing list