> De: "Tagir Valeev" <amae...@gmail.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>
> Cc: "Gavin Bierman" <gavin.bier...@oracle.com>, "amber-spec-experts"
> <amber-spec-experts@openjdk.java.net>
> Envoyé: Mercredi 4 Septembre 2019 07:21:48
> Objet: Re: Draft JLS spec for records

> Hello!

Hi ! 

>> 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.

> I don't think so. A compact constructor (or require initializer, as you 
> propose)
> could be not the only constructor. An instance initializer is convenient
> because it's added to every constructor, regardless of whether it's compact or
> not. So the new thing doesn't supersede the instance initializer and I see no
> good reason to explicitly disable it.

I've forgotten that you can have multiple constructors in a record too, 
I never liked that a class can have multiple constructors because it forces you 
to read the doc to choose between the constructors and i'm too lazy for that :) 

The problem with a record is that if you have multiple constructors, you may 
mix classical constructors with the compact one, 
like this 
record Foo(Object obj, int v) { 
public Foo(Object obj) { 
this.obj = obj; 
this.v = -1; 
} 

public Foo { 
Objects.requireNonNull(obj); // ensure obj is non null 
} 
} 

and i'm not sure that every readers will think seeing this code that new 
Foo(null) is allowed, 
and it will be worst if instead of a compact constructor syntax we have an 
require initializer syntax because as you said an instance initializer is 
copied in front of all constructors. 

I believe there are two ways to make sure a require initializer is always 
executed, 
either you specify that the require initializer is copied in all constructors 
but if the constructors have different parameters, you have to restrict the 
require initializer to see only the common parameters which seems to magical 
for me or you require explicit constructors to delegate to another constructor, 
so the code above is not valid because the first constructor doesn't call the 
canonical one. 
The code has to be changed to 
record Foo(Object obj, int v) { 
public Foo(Object obj) { 
this(obj, -1); 
} 

require { 
Objects.requireNonNull(obj); // ensure obj is non null 
} 
} 

regards, 
Rémi 

> With best regards,
> Tagir Valeev.

> On Tue, Sep 3, 2019 at 7:02 PM < [ mailto:fo...@univ-mlv.fr | 
> fo...@univ-mlv.fr
> ] > wrote:

>>> De: "Gavin Bierman" < [ mailto:gavin.bier...@oracle.com |
>>> gavin.bier...@oracle.com ] >
>>> À: "Remi Forax" < [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] >
>>> Cc: "Brian Goetz" < [ mailto:brian.go...@oracle.com | 
>>> brian.go...@oracle.com ]
>>> >, "amber-spec-experts" < [ mailto:amber-spec-experts@openjdk.java.net |
>>> amber-spec-experts@openjdk.java.net ] >
>>> Envoyé: Mardi 3 Septembre 2019 12:37:17
>>> Objet: Re: Draft JLS spec for records

>>> Thanks Remi.

>>>> - a canonical constructor can not have throws clause (from the text of the
>>>> section) but the grammar in 8.10.2 the CompactConstructor declaration can 
>>>> have
>>>> a throw clause ?

>>> That is just a typo - thanks. The rest I will get back to you shortly.

>> humm,
>> thinking more about the canonical constructor
>> - does'nt really need a modifier (it's always public if you believe the 
>> current
>> state of the spec or it's the one of the record anyway)
>> - doesn't need to declare a type parameter
>> - doesn't need annotations because you get the one from the record
>> so it's more like an initializer than a constructor.

>> 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.

>> An example that should not compile
>> record Foo(String s) {
>> require {
>> System.out.println("am i print first ?");
>> }
>> {
>> System.out.println("am i print first ?");
>> }
>> }

>>> Thanks,
>>> Gavin

>> Rémi

Reply via email to