On Sep 3, 2019, at 5:02 AM, fo...@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 {
      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

Reply via email to