Should JEP 468 derived withers be opt in?
Brian Goetz
brian.goetz at oracle.com
Thu Nov 7 15:57:39 UTC 2024
Record constructors are public and can (theoretically) set all the
fields. So if you have a record with invariants (such as "name != null"
or "x < y") these should be checked in the constructor.
If they are checked in the constructor, they will also be checked
implicitly in a `with` expression, since `with` expressions go back
through the constructor to produce the result.
It seems that in your example, the requirement you want to impose is
"when I call withName on a Something, I must update the time too." But
even without withers, your program doesn't enforce that:
Something s = new Something("Bob", randomTime());
Something ss = s.withName("Mary", s.updateTime());
So while ss is derived from s, they share the same update time. The
requirement you are trying to enforce is a "handshake" one: "when you
update something, set the update time." And if handshake enforcement is
enough without withers, it is enough with withers too:
ss = s with { name = "Mary"; updateTime = now(); }
On 11/7/2024 9:28 AM, Adam Gent wrote:
> One concern I have with "Withers" is that they don't codify the need or requirement of multiple fields to be set at the exact time.
>
> Currently folks are probably making static methods on records for creation. After (ab)using records in our code base that is less academic and more business we frequently have a time field.
>
> record Something(String name, Instant updateTime, ... other fields) {
> static Something withName(String name, Instant updateTime) {
> ...
> }
> // Other with methods always including updateTime.
> }
>
> I admit my example is poor but the idea is that we want to encodify that the time needs to be set on each call.
>
> If JEP 468 comes through one could create the record without specifying the time field. Basically withers allow each field to be updated independently. That is JEP 468 sort of increases the API of existing code.
>
> So I wonder if a safer backward compatibility is to provide some sort of marker annotation? e.g. `@Withers` placed on the record or some other way to mark that the record is safe to have withers.
>
> Thoughts?
>
> Cheers
> -Adam
More information about the amber-dev
mailing list