<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>Tuesday, January 20, 2026 10:43:56 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;"><font size="4" face="monospace">Fair point that we should be more
      precise about this.  For the record, here is how record equality
      currently works: <br><br>
      BRIEF HISTORICAL DIGRESSION<br><br>
      The `equals` and `hashCode` implementations are indeed derived
      from the fields, not the accessors.  To super-simplify the
      discussion (not to reopen it):<br><br>
       - 99.9% of the time, the user will not provide explicit
      accessors, and in these cases, it makes no difference.<br><br>
       - When a user does provide an explicit accessor, it will almost
      always be to perform a defensive copy.  <br><br>
         - If the thing being copied is a collection, the answer makes
      no difference (Collection::equals is contents-based) and using the
      accessor is much^2 more expensive<br><br>
         - If the thing being copied is an array, comparing the copy
      would use spurious identity and would be semnatically wrong -- so
      in this case you _always_ have to override equals anyway, so in
      this case it makes no difference<br><br>
      While this may seem like it is just guessing what users will do,
      this is actually rooted in the spec of Record::equals: <br><br><blockquote>Indicates whether some other object is
        "equal to" this one. In addition to the general contract of
        Object.equals, record classes must further obey the invariant
        that when a record instance is "copied" by passing the result of
        the record component accessor methods to the canonical
        constructor, as follows:<br>
              R copy = new R(r.c1(), r.c2(), ..., r.cn());</blockquote><br>
      So summarizing the past decision: it should never make a
      difference semantically whether we use the fields or the
      accessors.  Using the accessors is more formally correct, but in
      some cases, doing so would be dramatically more expensive without
      any benefit to the user.  So it seemed an acceptably pragmatic
      choice to use the fields rather than accessors.<br><br></font><font size="4" face="monospace">END DIGRESSION<br></font><br>
    <font size="4" face="monospace">Now, the question we should be
      discussing is: how should this implementation reality map to the
      goal of "records are degenerate carriers"?  </font></blockquote><div><br></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><br data-mce-bogus="1"></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 data-mce-bogus="1"></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 data-mce-bogus="1"></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 data-mce-bogus="1"></div><div>regards,</div><div>Rémi</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>
    <div class="moz-cite-prefix">On 1/20/2026 1:35 PM, <a class="moz-txt-link-abbreviated" 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></body></html>