Draft JLS spec for records

John Rose john.r.rose at oracle.com
Wed Sep 4 23:27:23 UTC 2019

On Sep 3, 2019, at 5:02 AM, forax at univ-mlv.fr wrote:
> Given that i've always find the syntax of the canonical constructor too close to the one of the real constructor (depending on the fact that parenthesis are present or not),
> i propose a new kind of initializer, the require initializer (obvisouly it can be another name than "require").
> An example of syntax:
>   record Foo(String s) {
>     require {
>       Objects.requireNonNull(s);
>     }
>   }
> I also believe we should make the instance initializer illegal in record given that a require initializer is a kind a better instance initializer because it can access local variables.

The reason those initializers cannot “see” constructor parameters is (as you noted later) the initializers are incorporated into every constructor, and thus cannot assume any particular set of parameter names.

OTOH, if you are incorporating only into the canonical constructor of a record, you *can* assume all component names are in scope.

In fact, OTOOH, in some sense *every* constructor of a record has *all* component names in scope, so the initializer of a record *could* have those names.  It doesn’t even have to be a new kind of initializer, just a new power of the existing initializer in the restricted context of a record, where all components are always in scope.

So (a) don’t add the keyword and (b) all instance initializers to access full context of a record’s components.  Brian will immediately say that this makes a questionable syntax choice (yes, I plead guilty to that) into an attractive nuisance, so that’s a reason to maybe require a keyword to opt into the nice new features of IIs.

OTO^3H, since the canonical constructor is central to a record in a special way, it makes perfect sense to (1) put all the juicy validation/normalization logic into the body of the main constructor, and (2) look for ways to slim down the syntax of that constructor so, in common cases, it looks as slim and friendly as an instance initializer.  So:

  record Foo(String s) {
    constructor {

But that’s so close to the proposed CompactConstructorDeclaration syntax that we are now arguing about matters of taste.

My taste-meter doesn’t budge for the missing parentheses of “Foo { }”, but the needle *does* twitch a little because of the obligation to say “public” before every compact constructor declaration.  Surely that’s not necessary.  Since interfaces *also* require certain members to be public, *and* they allow “public” to be elided, it seems like records should provide the same courtesy.  I’m sure that’s already been discussed, but I’ll add my vote for eliding “public” at that point.

— John

More information about the amber-spec-experts mailing list