On Sep 3, 2019, at 5:02 AM, [email protected] 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 {
Objects.requireNonNull(s);
}
}
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