Data Oriented Programming, Beyond Records

Olexandr Rotan rotanolexandr842 at gmail.com
Wed Jan 21 23:28:31 UTC 2026


I might be thinking at a slightly lower level here, but from a practical
standpoint, I would say that 99.9% of equals/hashcode implementations fall
into two general categories: they are either defined by a full state of the
object, or defined by some unque key.

KEY BASED EQUALITY RANT STARTS -----------

If premier is rather self-explanatory, latter may need further elaboration.
The "key" here is either an object identity, mostly for in-memory objects,
or some identity (say primary db key) or business (a subset of fields
uniquely identifying object, say user email or key pair (tenantId, table,
entityId)).

I believe that, practically speaking, "the mutability issue" actually comes
down to user wanting to use key-based equality instead of state-based,
otherwise I don't see much reason to have a conversation about whether or
not we want users to explicitly create an inappropriate for their case
full-state equals method themself. Besides that, as Archie pointed out,
cyclic structures are also case for identity-based equality, and (I would
dare to say perhaps most common) last major case is ORM models, especially
higher-level aggregates, comparing which by their full state would load
half of the db in memory.

RANT ENDS ------

So, this whole rant about key-based equality was to point out that the key
practical tension point would be users wanting/needing to override equality
to key-based, which covers widest variety of "full-state-equlity-misses"
possible.

I am not saying, not proposing to allow users to opt-in some components
into equality (and btw I believe even if there was such mechanism, opt-in
is better then opt-out), but if there were a feature like this for classes,
along with other carrier benefits (not necessarily as part fo this
feature), I believe that this would solve basically all the tensions.

Now, I understand that 2 is 2 times bigger than 1, and everyone wants to
keep language feature count as low as possible, but I believe there is
still value in recognizing this two almost-polar approaches to implementing
equality and acknowledging each of them has a wide range of use cases,
collectively covering virtually everything

On Thu, Jan 22, 2026, 00:32 Archie Cobbs <archie.cobbs at gmail.com> wrote:

> Thanks for the thoughtful replies & apologies for you being double-teamed
> in this thread today :)
>
> I like the conceptual aspects of carrier that it "reverse inherits" from
> record, i.e., it has a pull-apart operation, a put-together operation, and
> composing those two operations equals the identity operation (modulo
> equals() of course).
>
> I think it would have been a reasonable choice for records to use value
> equality instead of equals() equality, but that's a moot point now and
> anyway I can always @Override if needed so not a big deal. So practically
> speaking, at this point, I agree it makes sense for carriers to be
> consistent with that.
>
> The deals are not mutually exclusive.
>
>
> That's very good and in effect solves my problem, I think. Will one be
> able to declare a value record? (Is that a contradiction?) Otherwise,
> presumably it would have to be a concrete value carrier class... ?
>
> Thanks,
> -Archie
>
> --
> Archie L. Cobbs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20260122/c9711749/attachment-0001.htm>


More information about the amber-spec-observers mailing list