> De: "Brian Goetz" <brian.go...@oracle.com> > À: "Remi Forax" <fo...@univ-mlv.fr>, "Tagir Valeev" <amae...@gmail.com> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Envoyé: Jeudi 5 Septembre 2019 00:05:18 > Objet: Re: Draft JLS spec for records
> Ideally, records are classes, with restrictions (like enums). And again, > ideally, we find the minimal set of restrictions (e.g., "no instance fields"), > and then we get out of the way. > In the case of records, we have chosen to have a compact way to declare the > _canonical_ constructor. So they're not just classes with restrictions, but > classes with restrictions and small enhancements. But ultimately, the less we > depart from "records are classes", the fewer special rules the user has to > learn. > Therefore, I don't think we should go out of our way to restrict, or reinvent, > instance initializers; I think "legal but rare" is a fine place for this to > be. yes, i agree, "require" initializer does not worth the cost of making records different from classes. so long live the compact constructor, i suppose :) Rémi > On 9/4/2019 5:58 PM, [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] wrote: >>> De: "Tagir Valeev" [ mailto:amae...@gmail.com | <amae...@gmail.com> ] >>> À: "Remi Forax" [ mailto:fo...@univ-mlv.fr | <fo...@univ-mlv.fr> ] >>> Cc: "Gavin Bierman" [ mailto:gavin.bier...@oracle.com | >>> <gavin.bier...@oracle.com> ] , "amber-spec-experts" [ >>> mailto:amber-spec-experts@openjdk.java.net | >>> <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