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

David Alayachew davidalayachew at gmail.com
Sat Apr 20 19:00:49 UTC 2024


Strongly agreed. In fact, I'm ok even if it is only a warning.

But yes, this shadowing is definitely something I want to avoid at all
costs. I understand why it is there, and while I still don't agree with the
logic, I begrudgingly accept its existence. Still, in response to
shadowing, I always prepend every single instance field I have with `this`,
precisely so that I can avoid this problem in my normal code. If I am going
to be forced to do this for yet another layer, I want at least a warning.

Here is a slightly related post I made on amber-dev that addresses
something in a similar vein. It is a different form of shadowing.
https://mail.openjdk.org/pipermail/amber-dev/2024-April/008704.html

On Sat, Apr 20, 2024 at 1:49 PM <forax at univ-mlv.fr> wrote:

>
>
> ------------------------------
>
> *From: *"attila kelemen85" <attila.kelemen85 at gmail.com>
> *To: *"Remi Forax" <forax at univ-mlv.fr>
> *Cc: *"amber-dev" <amber-dev at openjdk.org>, "Gavin Bierman" <
> gavin.bierman at oracle.com>, "jdk-dev" <jdk-dev at openjdk.org>
> *Sent: *Saturday, April 20, 2024 7:35:34 PM
> *Subject: *Re: New candidate JEP: 468: Derived Record Creation (Preview)
>
> 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).
>
>
> Okay, got it !
>
> You are right, this is a serious issue, the semantics is different
> depending on if MyRecord has a field "z" or not.
>
> Rémi
>
>
> 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/6fc813cb/attachment-0001.htm>


More information about the jdk-dev mailing list