<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><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>"Brian Goetz" <brian.goetz@oracle.com><br><b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br><b>Cc: </b>"Viktor Klang" <viktor.klang@oracle.com>, "amber-spec-experts" <amber-spec-experts@openjdk.java.net><br><b>Sent: </b>Wednesday, January 21, 2026 7:01:52 PM<br><b>Subject: </b>Re: Data Oriented Programming, Beyond Records<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;"><br>
<br>
<blockquote cite="mid:1801122196.22401921.1769017000476.JavaMail.zimbra@univ-eiffel.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000">
<div>
<div>The other solution seems to allow a carrier class to not
be restricted to only describe data so like a record
equals/hashCode/toString are derived from the fields that
define a component.</div>
</div>
</div>
</blockquote>
<br>
I'd like to stay away from the "macro generator" view of the world,
and instead talk about semantics and conceptual models. The more we
describe things in terms of macro generation, the less users will be
able to _see_ the underlying concepts.<br>
<br>
I believe I had already anticipated and preemptively dismissed the
model you outline below, but I'm sure it was easy to miss. But
here's the problem: `component` fields are supposed to be
implementation details of _how_ a carrier class achieves the class
contract. Having the semantics of equality depend on which fields
are component fields has several big problems:<br>
<br>
- It means that clients can't reason about what equality means by
looking at the class declaration. <br>
<br>
- It means that the behavior of a class will change visibly under
harmless-looking implementation-only refactorings, such as migrating
a field from a component field to some other representation.</blockquote><div><br></div><div>yes, both are true, this is also true for any classes in general.</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;"><br>
<br>
- Having flung open the door labeled "macro generator", users will
instantly demand "I want this to be a component field to get the
accessor and constructor boilerplate, but I don't want it part of
equals, can I please have a modifier to condition what counts in
equals and hashCode, #kthxbye". This violates Rule Number One of
the record design, which is "no generation knobs, ever". Once you
have one, you are irrevocably on the road to Lombok.</blockquote><div><br data-mce-bogus="1"></div><div>I think this is true for any proposals that generate code for implementing a carrier class, including the one you propose before.</div><div><br data-mce-bogus="1"></div><div>When designing records, we have established that the only reasonable proposition that can not be labelled as a code generator is ... a record.</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;"><br>
<br>
So there are two stabled, principled alternatives:<br>
<br>
- Just don't ever try to derive equals and hashCode <br>
- Derive equals and hashCode similarly as for records<br>
<br>
And of course, the first means that records cannot be considered
special cases of carriers. So the latter seems a forced move. </blockquote><div><br></div><div>I still think there is value to consider that a carrier class is an abstract specification that just say that it can be constructed/deconstructed but equals/hashCode are user defined.</div><div><br data-mce-bogus="1"></div><div>When you use only pattern matching, you do not really need equals/hashCode to be defined, you recursively pattern-match until you have primitive values.</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;"> <br>
<br>
(Meta observation: it is easy, when you have your Code Generator hat
on, to suggest reasonable-seeming things that turn out to be
semantically questionable or surprising or inconsistent; this is why
we try so hard to approach this semantics-first.)</blockquote><div><br></div><div><br data-mce-bogus="1"></div><div>Rémi</div><div><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;"><br>
<br>
<blockquote cite="mid:1801122196.22401921.1769017000476.JavaMail.zimbra@univ-eiffel.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000">
<div>
<div>The carrier class feature:</div>
<div>A carrier class is a class that define "virtual"
components</div>
<div>- the accessors must be implemented or declared abstract</div>
<div>- the canonical constructor must be implemented if the
class is concrete</div>
<div>- the record pattern works using accessors.</div>
<div><br>
</div>
<div>A carrier class is not restricted to be a data class (so
no equals/hashCode/toString), it can represent any class
that can be constructed/deconstructed as several virtual
components.</div>
<div><br>
</div>
<div>The component field feature:</div>
<div>A field can be declared as "component", i.e. implementing
one of the virtual component</div>
<div>- the field is automatically strict</div>
<div>- the accessor corresponding to the field can be derived
(if not @Override)</div>
<div>- if at least one of the field is declared as component,
equals/hashCode/toString can be derived</div>
<div>- if at least one of the field is declared as component,
the compact constructor syntax is available and inside it,
all the fields marked as component are initialized
automatically</div>
<div>- if all virtual components have an associated component
field, the canonical constructor can be derived </div>
<div><br>
</div>
<div>regards,</div>
<div>Rémi</div>
<div><br>
</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;"><br>
<div class="moz-cite-prefix">On 1/20/2026 1:35 PM, <a class="moz-txt-link-abbreviated moz-txt-link-freetext" href="mailto:forax@univ-mlv.fr" target="_blank">forax@univ-mlv.fr</a> wrote:<br>
</div>
<blockquote cite="mid:1042190625.21334996.1768934120738.JavaMail.zimbra@univ-eiffel.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000">
<div><br>
</div>
<div><br>
</div>
<hr id="zwchr">
<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;"><b>From:
</b>"Brian Goetz" <a class="moz-txt-link-rfc2396E" href="mailto:brian.goetz@oracle.com" target="_blank"><brian.goetz@oracle.com></a><br>
<b>To: </b>"Remi Forax" <a class="moz-txt-link-rfc2396E" href="mailto:forax@univ-mlv.fr" target="_blank"><forax@univ-mlv.fr></a><br>
<b>Cc: </b>"Viktor Klang" <a class="moz-txt-link-rfc2396E" href="mailto:viktor.klang@oracle.com" target="_blank"><viktor.klang@oracle.com></a>,
"amber-spec-experts" <a class="moz-txt-link-rfc2396E" href="mailto:amber-spec-experts@openjdk.java.net" target="_blank"><amber-spec-experts@openjdk.java.net></a><br>
<b>Sent: </b>Tuesday, January 20, 2026 4:28:14 PM<br>
<b>Subject: </b>Re: Data Oriented Programming,
Beyond Records<br>
</blockquote>
</div>
<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;"><br>
<br>
<blockquote cite="mid:476261784.20721726.1768897040954.JavaMail.zimbra@univ-eiffel.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000">
<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;">
<blockquote cite="mid:1884486700.20372636.1768848050872.JavaMail.zimbra@univ-eiffel.fr">
<div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000">
<div>
<div>The modifier "component" is too
close to the "property" modifier I
wanted to include years ago, it's
just to sugary for its own good.</div>
</div>
</div>
</blockquote>
<br>
You know the rule; mention syntax and you
forfeit the right to more substantial
comments....</blockquote>
<div><br>
</div>
<div>I'm talking about the semantics,
especially the fact that equals/hashCode and
toString() are derived from.</div>
</div>
</div>
</blockquote>
<br>
Except that equals/hashCode have nothing to do with
the "component" modifier _at all_. They are derived
from the _state description_, in terms of the
_accessors_, whose existence is implied directly by
the _state description_. </blockquote>
<div><br>
</div>
<div>I do not think you can do that, because it means
that a record is not a carrier class.</div>
<div><br>
</div>
<div>Do you agree that equals() and hashCode() of a
record are not derived from the accessors ?</div>
<div><br>
</div>
<div>regards,</div>
<div>Rémi</div>
<div><br>
</div>
</div>
</div>
</blockquote>
<br>
<br>
</blockquote>
</div>
</div>
</blockquote>
<br><br></blockquote></div></div></body></html>