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