<html><body><div id="zimbraEditorContainer" style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000" class="23"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"attila kelemen85" <attila.kelemen85@gmail.com><br><b>To: </b>"amber-dev" <amber-dev@openjdk.org><br><b>Cc: </b>"Gavin Bierman" <gavin.bierman@oracle.com>, "jdk-dev" <jdk-dev@openjdk.org><br><b>Sent: </b>Saturday, April 20, 2024 5:49:22 PM<br><b>Subject: </b>Re: New candidate JEP: 468: Derived Record Creation (Preview)<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div dir="ltr">I have a backward compatibility concern about this JEP. Consider that I have the following record:<br><div>`record MyRecord(int x, int y) { }`<br></div><br><div>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:</div><br><div>```<br>record MyRecord(int x, int y, int z) {<br> public MyRecord(int x, int y) {<br> this(x, y, 0);<br> }<br>}<br>```<br></div><br><div>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:</div><br><div>```</div><div>var obj1 = new MyRecord(1, 2);<br>int z = 26;<br>var obj2 = obj1 with { y = z; }<br></div><div>```</div><br><div>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.</div><br><div>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.</div><br><div>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.</div><br><div>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.</div><br><div>Attila</div></div></blockquote><div><br></div><div>Hello, i think you are pre-supposing a specific compiler translation strategy, but it can be compiled like this:</div><div><br data-mce-bogus="1"></div><div>MyRecord obj1 = new MyRecord(1, 2);<br>int z = 26;</div><div><br data-mce-bogus="1"></div><div><div>Object carrier = indy(r); // create a carrier object by calling all the accessors</div><div> // so the side effects are done before calling the block</div><div>int y = z;</div><div>MyRecord obj2 = indy(carrier, /*y:*/ y); // create an instance of MyRecord using 'y' and the values in the carrier</div></div><div></div><div><br data-mce-bogus="1"></div><div>With the carrier instances working like https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/lang/runtime/Carriers.java</div><div><br data-mce-bogus="1"></div><div>regards,<br data-mce-bogus="1"></div><div>Rémi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;" data-mce-style="border-left: 2px solid #1010FF; margin-left: 5px; padding-left: 5px; color: #000; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Mark Reinhold <<a href="mailto:mark.reinhold@oracle.com" target="_blank" rel="noopener" data-mce-href="mailto:mark.reinhold@oracle.com">mark.reinhold@oracle.com</a>> ezt írta (időpont: 2024. febr. 28., Sze, 21:04):<br></div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left: 1px solid #cccccc; padding-left: 1ex;" data-mce-style="margin: 0px 0px 0px 0.8ex; border-left: 1px solid #cccccc; padding-left: 1ex;"><a href="https://openjdk.org/jeps/468" rel="noopener noreferrer" target="_blank" data-mce-href="https://openjdk.org/jeps/468">https://openjdk.org/jeps/468</a><br><br> Summary: Enhance the Java language with derived creation for<br> records. Records are immutable objects, so developers frequently create<br> new records from old records to model new data. Derived creation<br> streamlines code by deriving a new record from an existing record,<br> specifying only the components that are different. This is a preview<br> language feature.<br><br>- Mark</blockquote></div><br></blockquote></div></div></body></html>