Data Oriented Programming, Beyond Records

Brian Goetz brian.goetz at oracle.com
Tue Jan 20 21:43:56 UTC 2026


Fair point that we should be more precise about this.  For the record, 
here is how record equality currently works:

BRIEF HISTORICAL DIGRESSION

The `equals` and `hashCode` implementations are indeed derived from the 
fields, not the accessors.  To super-simplify the discussion (not to 
reopen it):

  - 99.9% of the time, the user will not provide explicit accessors, and 
in these cases, it makes no difference.

  - When a user does provide an explicit accessor, it will almost always 
be to perform a defensive copy.

    - 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

    - 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

While this may seem like it is just guessing what users will do, this is 
actually rooted in the spec of Record::equals:

> 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:
>       R copy = new R(r.c1(), r.c2(), ..., r.cn());

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.

END DIGRESSION

Now, the question we should be discussing is: how should this 
implementation reality map to the goal of "records are degenerate 
carriers"?

(It is hard to tell what your intent is here, whether you are merely 
trying to capture the details or cast doubt on the stated goal.  
Obviously something makes you uncomfortable, I wish we could try to 
identify and understand that before suggesting random changes to the 
mechanics.  Let's see if we can do that.)


On 1/20/2026 1:35 PM, forax at univ-mlv.fr wrote:
>
>
> ------------------------------------------------------------------------
>
>     *From: *"Brian Goetz" <brian.goetz at oracle.com>
>     *To: *"Remi Forax" <forax at univ-mlv.fr>
>     *Cc: *"Viktor Klang" <viktor.klang at oracle.com>,
>     "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
>     *Sent: *Tuesday, January 20, 2026 4:28:14 PM
>     *Subject: *Re: Data Oriented Programming, Beyond Records
>
>
>
>                 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.
>
>
>             You know the rule; mention syntax and you forfeit the
>             right to more substantial comments....
>
>
>         I'm talking about the semantics, especially the fact that
>         equals/hashCode and toString() are derived from.
>
>
>     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_. 
>
>
> I do not think you can do that, because it means that a record is not 
> a carrier class.
>
> Do you agree that equals() and hashCode() of a record are not derived 
> from the accessors ?
>
> regards,
> Rémi
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-experts/attachments/20260120/7e350672/attachment-0001.htm>


More information about the amber-spec-experts mailing list