Reader mail bag

Brian Goetz brian.goetz at
Mon Apr 20 18:18:14 UTC 2020

A number of comments have come in on the -comments list.  If you want to 
continue the discussion on any of these, please start a new thread.

Regarding the brief thread on do expressions:

> Hi All,
> I have seen your discussion regarding using a new expression to place
> field's initialization block with the field instead of in class/instance
> initializer.
> While I understand reluctance to introduce new keywords, there is the idea
> of using lazy static final fields [1] instead of complicated class static
> initializers.
> I think that scenario might also need a new expression more.
> Has there been any thoughts how to declare source-code static final field
> to be translated into a LazyValue backed by condy?
> Moreover, has there been any thoughts how to declare such field to throw
> checked exception on field read when its initialization might?
> Sorry if the issue has already been discussed.
> Thanks,
> Mateusz Romanowski

Regarding the j.l.Record superclass:

> Hi All,
> Do you think that specialization could be used for record's implicit
> methods, while rehabilitating meaning of @Override?
> specialized public abstract class j.l.Record<R extends j.l.Record<R>> {
>    specialized int hashCode();
>    specialized boolean equals(Object o);
>    specialized accessor for each RecordComponent;
> }
> Then for a record named Coordinates, the Coordinates.class  would only
> contain fields, constructor and explicitly overridden methods.
> Sorry if such idea has already been raised?
> Thanks,
> Mateusz

We did give some thought to making `Record` an F-bounded supetype, as 
`Enum` is.  We found (a) there is no current need for it, and f-bounds 
are a tool we should reserve for when they are really needed, and (b) 
doing so would increase the cost of specialization, since now `Record` 
must be specialized for each record class.  Further, the "specialized 
accessor for each component" is not something that can be easily 
expressed with the envisioned specialization mechanism.

Regarding a potential mismatch between the JEP and the spec:

> From:
> Maarten Van Puymbroeck <maarten.vanpuymbroeck at>
> Hello,
> Tagir's answer is clear, but some confusion might arise since the 
> grammar in the JEP [1] is not consistent with the spec [2].
> The JEP still says:
> |RecordConstructorDeclaration: {Annotation} {ConstructorModifier} 
> [TypeParameters] SimpleTypeName [Throws] ConstructorBody|
> Kind regards,
> Maarten.

Regarding "withers":

> Subject:
> "Setters" in records
> From:
> Mark Staller <mark.staller at>
> Dear Amber EG,
> According to JEP 359: Records (Preview), records will automatically
> acquire public read accessors. Have there been considerations about
> builder-like, automatically acquired public setters for each field?
> Let's look at a quick example to make this a little clearer.
> record Point(int x, int y) {
>     public Point x(int x) {
>         return new Point(x, y);
>     }
>     public Point y(int y) {
>         return new Point(x, y);
>     }
> }
> In this Point example, x(int x) and y(int y) would be automatically
> generated "setters". I could imagine, this way of building up your
> object might come in very handy. If this has already been considered and
> discarded, I would be very much interested in the reasoning.
> Thanks a and nice regards,
> Mark

We call these "withers", as they are essentially saying "this instance, 
but with y=3".  One could imagine a convention where the immutable 
equivalent of `setX(x)` is called `withX(x)`; while we are not proposing 
such a convention, it is a useful enough mental model.

The reason that these are not included in records is that not all 
records would want all the one-argument withers; if one of the 
components participates in an invariant, the author might prefer an API 
that replaces them all at once.  And its also arbitrary to stop with the 
one-argument ones, which leads to a (2^n) explosion of possibly-useless 
API methods.  We didn't think that every tuple needed 2^n withers, so we 
instead will let authors pick their own.

There's a bigger problem here, and one we also know is going to be an 
issue for inline classes, which is a more general way of describing a 
parameterized transform on immutable aggregates. There are many possible 
ways this could go, but so far we haven't found one we like (and are 
currently prioritizing other problems.)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list