Reader mail bag

Brian Goetz brian.goetz at oracle.com
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 gmail.com>
>
>
> 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 gmx.net>
>
>
> 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.)




More information about the amber-spec-observers mailing list