From vicente.romero at oracle.com Sat Nov 2 00:01:21 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Fri, 1 Nov 2019 20:01:21 -0400 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> Message-ID: <1f22a71d-d66d-f0ce-9df9-8bee29b94c67@oracle.com> Hi Gavin, At: 9.7.4 Where Annotations May Appear, it says: It is a compile-time error if an annotation of type /T/ is syntactically a modifier for: ... * ??? a record component but /T/ is not applicable to record component declarations, type contexts, type parameter declarations, field declarations, or method declarations. I think that it should say: parameter declarations instead of type parameter declarations. Vicente On 10/31/19 10:17 AM, Gavin Bierman wrote: > An updated draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html > > (Alongside is a draft JVM spec for this feature: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html > > ) > > As always, please email me any comments/thoughts/bugs. > > Thanks, > Gavin > > >> On 23 Aug 2019, at 22:25, Gavin Bierman wrote: >> >> A draft language spec for records is available at: >> >> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >> >> This spec doesn?t yet discuss varargs records - to appear in the next draft. >> >> All comments welcomed! >> >> Thanks, >> Gavin -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Mon Nov 4 19:09:03 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 4 Nov 2019 11:09:03 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <87bltu1sv7.fsf@mid.deneb.enyo.de> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <87bltu1sv7.fsf@mid.deneb.enyo.de> Message-ID: <2455a8ef-e357-79fc-3a7d-92ec91f88fa2@oracle.com> Florian, Thanks for drawing attention to this part of the spec: On 11/2/2019 3:21 AM, Florian Weimer wrote: > Is it allowed to declare a canonical constructor explicitly and make > it non-public? I think the naswer is no. But it's not quite obvious > from the spec, I think. JLS 8.10.4 defines a "canonical" ctor to be a public ctor whose formal parameter list is identical to the record header. If you explicitly declare a ctor whose formal parameter list is identical to the record header, but you do not make it public, then you have not declared a "canonical" ctor. You have declared a ctor that, by virtue of its signature, prevents an implicitly declared canonical ctor from being declared. This is so unfortunate that it deserves an error message, and you will get one. However, you are right that the spec is slightly misworded. It says "It is a compile-time error if a record declaration contains a canonical constructor declaration that is not public." but a "canonical" ctor is public by definition. It should say "It is a compile-time error if a record declaration contains a constructor declaration whose formal parameter list is identical to the record header of R, but which is not public." An alternative approach: JLS 8.10.4 could define a "canonical" ctor as follows: "Every record type R has a _canonical_ constructor, which is a constructor [note the silence on accessibility] whose formal parameter list is identical to the record header of R." ... and deem an implicitly declared canonical ctor to be public. Then, the compile-time error can be left alone, though I would reword it for clarity and for tonal agreement with '[exp|imp]licitly declared': "If a canonical constructor is explicitly declared, then it must be public, or a compile-time error occurs." The alternative approach is best because the sense of "canonical" is dominated by the signature -- just look at javac's error message "canonical record constructor must be public" which assumes that canonical-ness is obvious (signature-driven) and that the access modifier is a separate thing, so to speak. That seems a pretty natural view of things for the JLS to embody. (Sidebar: Why allow a compact ctor declaration to be non-public, when we control its grammar that could be hard-coded to use `public`?) (Sidebar: The compact ctor declaration should be introduced at the same time as "A canonical constructor can be explicitly declared ...". I recall privately discussing the flow of this section but can't find it easily. I suggest that 8.10.4 should be "Canonical Constructor of a Record" and that the sole non-canonical clause "A record declaration may contain constructor declarations." should live in 8.10.2 "Record Body" (not plural; yes, the title of 8.9.2 should drop the D-word too, which will happen auto-magically) ... 8.10.2 already says "may contain constructor and member declarations" but that opening paragraph should advertise the compact ctor's role in helping to initialize the member [because otherwise CompactConstructorDeclaration goes unexplained] ... the line will be hard to write and this mail is already long enough.) Alex From alex.buckley at oracle.com Mon Nov 4 21:54:16 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 4 Nov 2019 13:54:16 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <87wocfgyda.fsf@mid.deneb.enyo.de> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <87bltu1sv7.fsf@mid.deneb.enyo.de> <2455a8ef-e357-79fc-3a7d-92ec91f88fa2@oracle.com> <87wocfgyda.fsf@mid.deneb.enyo.de> Message-ID: <85d2ca19-8c22-e494-0552-1d34f624d539@oracle.com> On 11/4/2019 12:50 PM, Florian Weimer wrote: > I think we are looking at different versions of the spec. I don't see > either wording here: > > > > But the updated wording works for me. Doh, you're right, and the updated spec already reflects some of the re-structuring I talked about in mail. However, the thrust of my comments about detaching 'public' and 'throws' from the definition of "canonical" still apply. The 2019-10-31 spec says "If the canonical constructor is not explicitly declared, then it is implicitly declared." but it is not possible to implicitly declare `public R(int i)` if the pretender `R(int i)` has been explicitly declared in `record R(int i)`. Yes, there is an error mandated for the pretender -- "The erasure of the signature of the constructor must not be equal to the erasure of the signature of the canonical constructor." -- but (1) A compiler vendor now has an impossible thing mandated on the one hand and a must-not-be-equal error mandated on the other hand, so which should be reported first? and (2) While it's appropriate to mention erasure when contrasting List and List (e.g. the javac test case), it's confusing to mention erasure when dealing with int and int. The JLS should be more explicit about how mis-declared modifiers and 'throws' are handled. Alex From vicente.romero at oracle.com Tue Nov 5 13:28:32 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Tue, 5 Nov 2019 08:28:32 -0500 Subject: question about java.lang.reflect.RecordComponent API Message-ID: Hi, I have got some comments in the CSR [1], that affect the API of java.lang.reflect.RecordComponent. As I have also received comments on the opposite direction I think this deserves a broader discussion. Some context I have added a toString method to RecordComponent after a review comment. The proposal was to make the method similar to java.lang.reflect.Field::toString so the current spec of the method is: /** * Returns a string describing this record component, including * its generic type. The format is: the generic record component type, * followed by a space, followed by the fully-qualified name of the * record class declaring the record component, followed by a period, * followed by the name of the record component. * * @return a string describing this record component, including its * generic type */ On the other hand I got another suggestion to make the method more similar to java.lang.reflect.Parameter, so removing the record class declaring the component from the resulting string. Which direction do we want to go? Consider that there is already a similar method, ::toGenericString, with spec: /** * Returns a string describing this record component, including * its generic type. The format is: the generic record component type, * followed by a space, followed by the fully-qualified name of the * record class declaring the record component, followed by a period, * followed by the name of the record component. * * @return a string describing this record component, including its * generic type */ So any decision here should affect both. In addition I got another suggestion to add a new method to j.l.r.RecordComponent: `getDeclaringRecord` on the lines of j.l.r.Parameter::getDeclaringExecutable. Comments? Vicente [1] https://bugs.openjdk.java.net/browse/JDK-8233436 -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Tue Nov 5 14:21:25 2019 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 5 Nov 2019 14:21:25 +0000 Subject: question about java.lang.reflect.RecordComponent API In-Reply-To: References: Message-ID: Hi Vicente, some random thoughts below. 1) A record component is *neither* a field, *nor* a method parameter. So, IMHO we should resist to all siren songs pushing for consistency in this or that direction. The spec is very clear on that: "A record type R has the following members: ??? For each record component appearing in the record component list: ??????? An implicitly declared private final field with the same name as the record component and the type as the declared type of the record component. This field is annotated with the annotation that appears on the corresponding record component, if this annotation type is applicable to a field declaration or type context. " That is, the record component is not even a member of the declaring record - the implicit private field is! So, on the basis of the spec I see no reason to bend the API this or that way. 2) Can you please confirm that RecordComponent::toString() is NOT printing generic type info? 3) A backlink from the component to the record declaration might be useful, and might shift the balance towards a more compact "int x" instead of "int Point.x" 4) We could also break with the past (after all this is a _new_ concept) and come up with a new way to rehash the same info, although, I have to admit it is quite hard to put (i) owner (ii) type and (iii) name in the same place w/o having my eyes hurt. "Point::(int x)" meh Given I'm not super confident we will solve (4) any time soon, I think what we're doing now represents a pretty defensible fallback option. As I said, if we feel strongly about adding the backlink to the declaring record (which of course makes sense), we might considering shifting the polarity from more verbose (int Point.x) to more compact (int x). Maurizio On 05/11/2019 13:28, Vicente Romero wrote: > > Hi, > > I have got some comments in the CSR [1], that affect the API of > java.lang.reflect.RecordComponent. As I have also received comments on > the opposite direction I think this deserves a broader discussion. > Some context I have added a toString method to RecordComponent after a > review comment. The proposal was to make the method similar to > java.lang.reflect.Field::toString so the current spec of the method is: > > /** * Returns a string describing this record component, including * > its generic type. The format is: the generic record component type, * > followed by a space, followed by the fully-qualified name of the * > record class declaring the record component, followed by a period, * > followed by the name of the record component. * * @return a string > describing this record component, including its * generic type */ > > On the other hand I got another suggestion to make the method more > similar to java.lang.reflect.Parameter, so removing the record class > declaring the component from the resulting string. Which direction do > we want to go? Consider that there is already a similar method, > ::toGenericString, with spec: > > /** * Returns a string describing this record component, including * > its generic type. The format is: the generic record component type, * > followed by a space, followed by the fully-qualified name of the * > record class declaring the record component, followed by a period, * > followed by the name of the record component. * * @return a string > describing this record component, including its * generic type */ > > So any decision here should affect both. In addition I got another > suggestion to add a new method to j.l.r.RecordComponent: > `getDeclaringRecord` on the lines of > j.l.r.Parameter::getDeclaringExecutable. Comments? > > Vicente > > [1] https://bugs.openjdk.java.net/browse/JDK-8233436 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From vicente.romero at oracle.com Tue Nov 5 14:42:44 2019 From: vicente.romero at oracle.com (Vicente Romero) Date: Tue, 5 Nov 2019 09:42:44 -0500 Subject: question about java.lang.reflect.RecordComponent API In-Reply-To: References: Message-ID: Hi Maurizio, Thanks for your feedback. It seems like we have material for today's meeting :) On 11/5/19 9:21 AM, Maurizio Cimadamore wrote: > > Hi Vicente, > some random thoughts below. > > 1) A record component is *neither* a field, *nor* a method parameter. > So, IMHO we should resist to all siren songs pushing for consistency > in this or that direction. The spec is very clear on that: > > "A record type R has the following members: > > ??? For each record component appearing in the record component list: > > ??????? An implicitly declared private final field with the same name > as the record component and the type as the declared type of the > record component. This field is annotated with the annotation that > appears on the corresponding record component, if this annotation type > is applicable to a field declaration or type context. > " > > That is, the record component is not even a member of the declaring > record - the implicit private field is! So, on the basis of the spec I > see no reason to bend the API this or that way. > > 2) Can you please confirm that RecordComponent::toString() is NOT > printing generic type info? > no it is not, > > 3) A backlink from the component to the record declaration might be > useful, and might shift the balance towards a more compact "int x" > instead of "int Point.x" > > 4) We could also break with the past (after all this is a _new_ > concept) and come up with a new way to rehash the same info, although, > I have to admit it is quite hard to put (i) owner (ii) type and (iii) > name in the same place w/o having my eyes hurt. "Point::(int x)" meh > > > Given I'm not super confident we will solve (4) any time soon, I think > what we're doing now represents a pretty defensible fallback option. > As I said, if we feel strongly about adding the backlink to the > declaring record (which of course makes sense), we might considering > shifting the polarity from more verbose (int Point.x) to more compact > (int x). > > Maurizio > Vicente > > On 05/11/2019 13:28, Vicente Romero wrote: >> >> Hi, >> >> I have got some comments in the CSR [1], that affect the API of >> java.lang.reflect.RecordComponent. As I have also received comments >> on the opposite direction I think this deserves a broader discussion. >> Some context I have added a toString method to RecordComponent after >> a review comment. The proposal was to make the method similar to >> java.lang.reflect.Field::toString so the current spec of the method is: >> >> /** * Returns a string describing this record component, including * >> its generic type. The format is: the generic record component type, * >> followed by a space, followed by the fully-qualified name of the * >> record class declaring the record component, followed by a period, * >> followed by the name of the record component. * * @return a string >> describing this record component, including its * generic type */ >> >> On the other hand I got another suggestion to make the method more >> similar to java.lang.reflect.Parameter, so removing the record class >> declaring the component from the resulting string. Which direction do >> we want to go? Consider that there is already a similar method, >> ::toGenericString, with spec: >> >> /** * Returns a string describing this record component, including * >> its generic type. The format is: the generic record component type, * >> followed by a space, followed by the fully-qualified name of the * >> record class declaring the record component, followed by a period, * >> followed by the name of the record component. * * @return a string >> describing this record component, including its * generic type */ >> >> So any decision here should affect both. In addition I got another >> suggestion to add a new method to j.l.r.RecordComponent: >> `getDeclaringRecord` on the lines of >> j.l.r.Parameter::getDeclaringExecutable. Comments? >> >> Vicente >> >> [1] https://bugs.openjdk.java.net/browse/JDK-8233436 >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Tue Nov 5 18:28:54 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 5 Nov 2019 19:28:54 +0100 (CET) Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <2008037526.1327972.1572539088614.JavaMail.zimbra@u-pem.fr> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <2008037526.1327972.1572539088614.JavaMail.zimbra@u-pem.fr> Message-ID: <1162551288.1336482.1572978533998.JavaMail.zimbra@u-pem.fr> >> De: "Gavin Bierman" >> ?: "amber-spec-experts" , "amber-dev" >> >> Envoy?: Jeudi 31 Octobre 2019 15:17:34 >> Objet: Updated Draft specs for JEP 359 (Records) >> An updated draft language spec for JEP 359 (Records) is available at: >> [ >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >> | >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >> ] >> (Alongside is a draft JVM spec for this feature: >> [ >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >> | >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >> ] >> ) > I've read the JVMS draft, it's ok for me. > I still think that not supporting @Deprecated on a record component is a > mistake. > Both Scala [1] and C# support deprecating ""property"", so we know that there is > a need. > And let's not forget that at some point in the future, Scala or Kotlin may want > to retrofit their case class/data class to record when possible to have a > better Java integration. >> As always, please email me any comments/thoughts/bugs. > regards, > R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From gavin.bierman at oracle.com Wed Nov 6 13:35:06 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Wed, 6 Nov 2019 13:35:06 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <87bltu1sv7.fsf@mid.deneb.enyo.de> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <87bltu1sv7.fsf@mid.deneb.enyo.de> Message-ID: <800C8889-7D4B-4D21-B744-150121D6CEF4@oracle.com> > On 2 Nov 2019, at 10:21, Florian Weimer wrote: > > * Gavin Bierman: > >> An updated draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >> > > Is it allowed to declare a canonical constructor explicitly and make > it non-public? I think the naswer is no. But it's not quite obvious > from the spec, I think. As Brian has said, no it is not possible. I will take another look at the spec to see if I can make this clearer. Thanks, Gavin From alex.buckley at oracle.com Wed Nov 6 18:21:50 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 6 Nov 2019 10:21:50 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> Message-ID: <455d46c1-8891-3312-f111-86884955f6c9@oracle.com> On 10/31/2019 7:17 AM, Gavin Bierman wrote: > (Alongside is a draft JVM spec for this feature: > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html > ) I looked at this for the CSR JDK-8233595. The `component_info` structure which is mentioned all over the place really tripped me up. Unlike fields and methods, a component isn't a first-class JVM construct, so a simple (i.e. unqualified) name is not deserved. Even the JLS always uses the qualified name, "record component" (if nothing else, to distinguish from "array component"). It would be wrong to replace mentions of the `component_info` structure with mentions of the `Record_attribute` structure, because `Record_attribute` isn't literally the structure which holds attributes (whereas the oft-mentioned `Code_attribute` structure really is). It would also be clunky to spell out "the `component_info` structure of the `Record_attribute` structure" in many places. For spec clarity, please rename `component_info` to `record_component_info`. (From a search of internal mail, I believe `component_info` was introduced around 7/24 in a discussion about annotations on record components, as an alternative to reusing the `field_info` structure in Record. Now that the term has spread throughout JVMS ch.4, it's time to name it properly.) As an aside, please drop "We're being intentionally vague here about just what it means for a class to have a "component"." and strengthen the opener: "The Record attribute is a variable-length attribute in the attributes table of a ClassFile structure. ***A `Record` attribute indicates that this class is a _record type_ (JLS ?8.10), declared with a list of _record components_.***" [Almost certainly declared _in source code_, but maybe this class file was auto-generated, so no need to say how the record type was declared ... but it was, since here we are in its class file.] Alex From gavin.bierman at oracle.com Fri Nov 8 15:28:12 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 8 Nov 2019 15:28:12 +0000 Subject: Reminder about draft specs Message-ID: I just wanted to draw your attention to the four (sorry!) specs for features we are hoping to ship with JDK14: http://cr.openjdk.java.net/~gbierman/jep361/jep361-20190927/specs/switch-expressions-jls.html http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html We appreciate all comments! Thanks, Gavin -------------- next part -------------- An HTML attachment was scrubbed... URL: From chris.hegarty at oracle.com Fri Nov 8 17:11:02 2019 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Fri, 8 Nov 2019 17:11:02 +0000 Subject: Reminder about draft specs In-Reply-To: References: Message-ID: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> Gavin, > On 8 Nov 2019, at 15:28, Gavin Bierman wrote: > > ... > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html Looks good. A comment relating to Serialization, from section 8.10.1 - Record Components. As all record types are subclasses of the class java.lang.Record which in turn implements the interface java.io.Serializable, it is necessary to ? This is not true. j.i.Record does not implement Serializable. Not all records are serializable. A record may be serializable, if it implements the java.io.Serializable interface, but it is not required. For example, record SerializableFoo (int x, int y) implements java.io.Serializable { } Additionally, I thought that all serialization related magic members were to be restricted from being record component names ( they are just too odd and potentially confusing ) ? The spec has some, but not all. The complete list ( of 7 ) is: writeObject, readObject, readObjectNoData, writeReplace, readResolve, serialVersionUID, serialPersistentFields. -Chris. -------------- next part -------------- An HTML attachment was scrubbed... URL: From john.r.rose at oracle.com Sat Nov 9 04:57:14 2019 From: john.r.rose at oracle.com (John Rose) Date: Fri, 8 Nov 2019 20:57:14 -0800 Subject: Reminder about draft specs In-Reply-To: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> References: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> Message-ID: I like the (de-)serialization specification for records, because it is a minimum cut on the existing specification. A day may come when a new serialization is based on something like expression trees which are executed to produce the deserialized values? but it is not THIS day, as Aragorn might say. In order to emphasize the incremental relation of record serialization to what has gone before, it would be helpful (even if only as a blog post) to show how the effect of record serialization, as documented in the proposed spec., would look if it were hand-coded using today?s serialization. I guess what I?m saying is that records can be demystified if they can be (as much as possible) described in terms of the boilerplate you would be forced to write, if you wanted the proposed behavior, but didn?t have the proposed feature. Make sense? ? John On Nov 8, 2019, at 9:11 AM, Chris Hegarty wrote: > > Gavin, > >> On 8 Nov 2019, at 15:28, Gavin Bierman > wrote: >> >> ... >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html > Looks good. A comment relating to Serialization, from section 8.10.1 - Record Components. > > As all record types are subclasses of the class java.lang.Record which in turn implements the interface java.io.Serializable, it is necessary to ? > > > This is not true. j.i.Record does not implement Serializable. Not all records are serializable. > > A record may be serializable, if it implements the java.io .Serializable interface, but it is not required. For example, > > record SerializableFoo (int x, int y) implements java.io.Serializable { } > > Additionally, I thought that all serialization related magic members were to be restricted from being record component names ( they are just too odd and potentially confusing ) ? The spec has some, but not all. The complete list ( of 7 ) is: writeObject, readObject, readObjectNoData, writeReplace, readResolve, serialVersionUID, serialPersistentFields. > > -Chris. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gavin.bierman at oracle.com Sat Nov 9 10:50:59 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Sat, 9 Nov 2019 10:50:59 +0000 Subject: Reminder about draft specs In-Reply-To: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> References: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> Message-ID: <8C91EF45-5BC4-49B2-BF2E-6CA17E72731F@oracle.com> Yes, that needs correcting. Let me tweak - will send another message when it?s completed. Thanks, Gavin > On 8 Nov 2019, at 17:11, Chris Hegarty wrote: > > Gavin, > >> On 8 Nov 2019, at 15:28, Gavin Bierman > wrote: >> >> ... >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html > Looks good. A comment relating to Serialization, from section 8.10.1 - Record Components. > > As all record types are subclasses of the class java.lang.Record which in turn implements the interface java.io.Serializable, it is necessary to ? > > > This is not true. j.i.Record does not implement Serializable. Not all records are serializable. > > A record may be serializable, if it implements the java.io .Serializable interface, but it is not required. For example, > > record SerializableFoo (int x, int y) implements java.io.Serializable { } > > Additionally, I thought that all serialization related magic members were to be restricted from being record component names ( they are just too odd and potentially confusing ) ? The spec has some, but not all. The complete list ( of 7 ) is: writeObject, readObject, readObjectNoData, writeReplace, readResolve, serialVersionUID, serialPersistentFields. > > -Chris. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From amaembo at gmail.com Sat Nov 9 11:07:29 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Sat, 9 Nov 2019 18:07:29 +0700 Subject: [records] Compact constructor type parameters Message-ID: Hello! Reading the latest JLS spec draft for records, chapter 8.10.5 [1] I see the following: A compact constructor declaration provides an alternative, succinct means to declare a canonical constructor for a record type. CompactConstructorDeclaration:{ Annotation } { ConstructorModifier } [ TypeParameters ] SimpleTypeName ConstructorBody Is it really useful to allow type parameters specification for a compact constructor, given that we cannot alter the formal parameters list, thus we cannot use them there? Yes, we could use them to declare local variables but this is an implementation detail, thus it should not leak to the clients (especially given the fact that canonical constructors are always public). Should not we exclude type parameters from the compact constructor declaration? I think we can go even further and disable type parameters for explicit canonical constructor declaration (not in compact form) as well. WDYT? With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.5 From amaembo at gmail.com Sat Nov 9 11:37:23 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Sat, 9 Nov 2019 18:37:23 +0700 Subject: [records] Non-compact canonical constructors Message-ID: Hello! Reading the latest JLS spec draft for records, chapter 8.10.4 [1] I see the following: For a record type R, the canonical constructor is a public constructor whose formal parameter list is identical to the record component list of R, with no throws clause. If the canonical constructor is explicitly declared, then it must satisfy the following; otherwise a compile-time error occurs: - The body of the canonical constructor must not contain a return statement (14.17). - Every field corresponding to a record component of R must be definitely assigned and moreover not definitely unassigned (16.9) at the end of the body of the canonical constructor. - All the other rules for a constructor in a normal class declaration must be satisfied (8.8). Several points are unclear to me 1. It's not explicitly specified whether an explicitly declared canonical constructor must be 'public' like it's specified for compact constructors. Does this mean that I can declare non-public canonical constructor? 2. I see the restriction for not having a return statement quite arbitrary. I understand it for compact constructors but see no reason for this restriction in non-compact canonical constructors. Could anybody provide a rationale behind this restriction? Sorry if it was discussed; in this case, links to the discussion would also be appreciated. 3. As it's already mentioned in 8.10.3, each record component implies an implicitly declared private final field. And as 8.3.1.2 [2] says, "A blank final instance variable must be definitely assigned and moreover not definitely unassigned at the end of every constructor of the class in which it is declared". Thus "Every field corresponding to a record component of R must be definitely assigned and moreover not definitely unassigned..." part seems redundant as it's covered by normal constructor rules. Probably it's not harmful to specify this explicitly though. 4. While this can be deduced from other parts of the spec I would explicitly add that an explicit constructor invocation statement (8.8.7.1) is disallowed in canonical constructor (including the compact form). E.g.: If the canonical constructor is explicitly declared, then it must satisfy the following; otherwise a compile-time error occurs: - The body of the canonical constructor must not contain an explicit constructor invocation statement (?8.8.7.1). ... Note that 8.9.2 (enum body declaration) contains the similar statement: It is a compile-time error if a constructor declaration in an enum declaration contains a superclass constructor invocation statement (?8.8.7.1). With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.3.1.2 From brian.goetz at oracle.com Sat Nov 9 11:47:49 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Sat, 9 Nov 2019 12:47:49 +0100 Subject: [records] Compact constructor type parameters In-Reply-To: References: Message-ID: <567B63C0-7987-4AB8-AA8B-3342B5F1C488@oracle.com> This is reasonable and probably easy to spec: when we define the canonical ctor, in addition to defining its is defined to have no type parameters. Since the compact ctor is shorthand for a full canonical ctor, no additional spec is needed for that. Sent from my iPad > On Nov 9, 2019, at 12:07 PM, Tagir Valeev wrote: > > Hello! > > Reading the latest JLS spec draft for records, chapter 8.10.5 [1] I > see the following: > > A compact constructor declaration provides an alternative, succinct > means to declare a canonical constructor for a record type. > CompactConstructorDeclaration:{ Annotation } { ConstructorModifier } [ > TypeParameters ] SimpleTypeName ConstructorBody > > Is it really useful to allow type parameters specification for a > compact constructor, given that we cannot alter the formal parameters > list, thus we cannot use them there? Yes, we could use them to declare > local variables but this is an implementation detail, thus it should > not leak to the clients (especially given the fact that canonical > constructors are always public). Should not we exclude type parameters > from the compact constructor declaration? > > I think we can go even further and disable type parameters for > explicit canonical constructor declaration (not in compact form) as > well. WDYT? > > With best regards, > Tagir Valeev. > > [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.5 From forax at univ-mlv.fr Sat Nov 9 13:31:48 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 9 Nov 2019 14:31:48 +0100 (CET) Subject: Record canonical constructor is required to be public Message-ID: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> I know we already discuss that but i still don't understand why a canonical constructor has to be public. I understand that a canonical constructor is not a simple constructor because it is also used as a kind of default de-constructor, but this doesn't work well with the current rules for constructors in nested classes/enums and if the class is not visible, it's constructor is not visible anyway. As Brian said in its presentation at Devoxx, records can be used to represent local nominal tuples, like public void foo() { record Pair(String name, int value); ... } If one want to add a requireNonNull using a compact constructor, it will be public void foo() { record Pair(String name, int value) { public Pair { Objects.requireNonNull(name); } } ... } having to declare the constructor to be public in that case seems weird. Mandating that the canonical constructor (hence the compact constructor) to be public: - goes against the idea of encapsulation that a constructor like any members should be the least visible - goes against the rules of default constructors (default constructor use the same visibility as their class) [1] - goes against the rules of constructors in enums (use private or package private depending on the kind of enums) [2] So we a set of rules in the JLS that follows the idea that a constructor should not be public by default in nested classes [1] but the rule for a canonical constructor doesn't follow the same idea [3], this should be fixed. In my opinion, the rule for a canonical constructor should be the same as the rule for a default constructor. regards, R?mi [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9 [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2 [3] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 From forax at univ-mlv.fr Sat Nov 9 13:48:21 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Sat, 9 Nov 2019 14:48:21 +0100 (CET) Subject: Record attribut should allow Deprecate atribute on record component Message-ID: <1967437784.70080.1573307301315.JavaMail.zimbra@u-pem.fr> Currently the JVMS spec for record doesn't allow a record component to be deprecated. The are several languages, some that run on the JVM like Kotlin or Scala that have a similar concept of record components and for all of them they allow to deprecate it, it should be a no brainer to allow a record component to be deprecated but the current draft of the spec doesn't allow that [1]. The table 4.7-C the line about the Deprecated attribut should list component_info has possible location. regards, R?mi [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html#jvms-4.7 From amaembo at gmail.com Sat Nov 9 14:59:19 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Sat, 9 Nov 2019 21:59:19 +0700 Subject: Record canonical constructor is required to be public In-Reply-To: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> References: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> Message-ID: Hello! The enum argument "goes against the rules of constructors in enums (use private or package private depending on the kind of enums)" is not appealing to me, as enum instances are never created explicitly, so nobody actually needs public enum constructors. I also don't agree with encapsulation argument. The record is a transparent entity, which doesn't need the encapsulation. If you need an encapsulation, you don't need a record. I, however, agree that specifying 'public' on a local record constructor looks weird. Probably specifying that canonical constructor visibility is the same as record visibility would be good. With best regards, Tagir Valeev. On Sat, Nov 9, 2019 at 8:32 PM Remi Forax wrote: > > I know we already discuss that but i still don't understand why a canonical constructor has to be public. > > I understand that a canonical constructor is not a simple constructor because it is also used as a kind of default de-constructor, but this doesn't work well with the current rules for constructors in nested classes/enums and if the class is not visible, it's constructor is not visible anyway. > > As Brian said in its presentation at Devoxx, records can be used to represent local nominal tuples, like > > public void foo() { > record Pair(String name, int value); > ... > } > > If one want to add a requireNonNull using a compact constructor, it will be > public void foo() { > record Pair(String name, int value) { > public Pair { > Objects.requireNonNull(name); > } > } > ... > } > > having to declare the constructor to be public in that case seems weird. > > Mandating that the canonical constructor (hence the compact constructor) to be public: > - goes against the idea of encapsulation that a constructor like any members should be the least visible > - goes against the rules of default constructors (default constructor use the same visibility as their class) [1] > - goes against the rules of constructors in enums (use private or package private depending on the kind of enums) [2] > > So we a set of rules in the JLS that follows the idea that a constructor should not be public by default in nested classes [1] but the rule for a canonical constructor doesn't follow the same idea [3], this should be fixed. > > In my opinion, the rule for a canonical constructor should be the same as the rule for a default constructor. > > regards, > R?mi > > > [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9 > [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2 > [3] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 From amaembo at gmail.com Sat Nov 9 15:31:18 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Sat, 9 Nov 2019 22:31:18 +0700 Subject: Draft JLS spec for records - local types In-Reply-To: <4CA095B6-C83D-4F6A-BC09-121469FF5C21@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <2452487.ezX9TyzB4F@cube> <4CA095B6-C83D-4F6A-BC09-121469FF5C21@oracle.com> Message-ID: Hello! > Local records should be allowed; we should probably allow local enums at the same time. On the other hand, local classes also may have an implicit state which consists of captured variables and possibly captured `this` reference as well. Usually, all instances of local classes that can interact with each other have the same captured state, but it's not impossible to have two instances with the different captured state. E.g.: public static void main(String[] args) { foo(0); } static Object foo(int x) { class Foo { int getX() { return x; } } if (x == 1) { return new Foo(); } Foo foo1 = new Foo(); Foo foo2 = (Foo) foo(1); System.out.println(foo1.getX()); // prints 0 System.out.println(foo2.getX()); // prints 1 return null; } If we allow local records, they would also have an implicit state, that "hidden extra component". E.g. if we define a record without components instead of class Foo in the example above, its `equals` method would return true for `foo1` and `foo2`, yet they have different behavior. Is it still ok? With best regards, Tagir Valeev. From forax at univ-mlv.fr Sat Nov 9 16:37:51 2019 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Sat, 9 Nov 2019 17:37:51 +0100 (CET) Subject: Record canonical constructor is required to be public In-Reply-To: References: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> Message-ID: <950349200.84317.1573317471821.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Tagir Valeev" > ?: "Remi Forax" > Cc: "amber-spec-experts" > Envoy?: Samedi 9 Novembre 2019 09:59:19 > Objet: Re: Record canonical constructor is required to be public > Hello! > > The enum argument "goes against the rules of constructors in enums > (use private or package private depending on the kind of enums)" is > not appealing to me, as enum instances are never created explicitly, > so nobody actually needs public enum constructors. I also don't agree > with encapsulation argument. The record is a transparent entity, which > doesn't need the encapsulation. If you need an encapsulation, you > don't need a record. I, however, agree that specifying 'public' on a > local record constructor looks weird. Probably specifying that > canonical constructor visibility is the same as record visibility > would be good. I use enum as an example where the spec takes care to not allow a constructor with an accessibility wider than what its needed. For encapsulation, i've used the wrong term, it's about the russian dolls way of Java sees accessibility, if the package is not visible, the class is not visible, likewise if the class is not visible, the constructor is not visible, so requiring a public constructor on a non visible class is useless. > > With best regards, > Tagir Valeev. regards, R?mi > > On Sat, Nov 9, 2019 at 8:32 PM Remi Forax wrote: >> >> I know we already discuss that but i still don't understand why a canonical >> constructor has to be public. >> >> I understand that a canonical constructor is not a simple constructor because it >> is also used as a kind of default de-constructor, but this doesn't work well >> with the current rules for constructors in nested classes/enums and if the >> class is not visible, it's constructor is not visible anyway. >> >> As Brian said in its presentation at Devoxx, records can be used to represent >> local nominal tuples, like >> >> public void foo() { >> record Pair(String name, int value); >> ... >> } >> >> If one want to add a requireNonNull using a compact constructor, it will be >> public void foo() { >> record Pair(String name, int value) { >> public Pair { >> Objects.requireNonNull(name); >> } >> } >> ... >> } >> >> having to declare the constructor to be public in that case seems weird. >> >> Mandating that the canonical constructor (hence the compact constructor) to be >> public: >> - goes against the idea of encapsulation that a constructor like any members >> should be the least visible >> - goes against the rules of default constructors (default constructor use the >> same visibility as their class) [1] >> - goes against the rules of constructors in enums (use private or package >> private depending on the kind of enums) [2] >> >> So we a set of rules in the JLS that follows the idea that a constructor should >> not be public by default in nested classes [1] but the rule for a canonical >> constructor doesn't follow the same idea [3], this should be fixed. >> >> In my opinion, the rule for a canonical constructor should be the same as the >> rule for a default constructor. >> >> regards, >> R?mi >> >> >> [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9 >> [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2 >> [3] > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 From john.r.rose at oracle.com Sat Nov 9 18:27:31 2019 From: john.r.rose at oracle.com (John Rose) Date: Sat, 9 Nov 2019 10:27:31 -0800 Subject: Record canonical constructor is required to be public In-Reply-To: References: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> Message-ID: <4FB56306-BC7D-4B5C-8509-E347CF7AAF46@oracle.com> On Nov 9, 2019, at 6:59 AM, Tagir Valeev wrote: > > Probably specifying that > canonical constructor visibility is the same as record visibility > would be good. +1 to that suggestion, although I admit I don?t know the full set of design considerations. It?s coherent with some basic rules that already align constructor and class access. -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Sun Nov 10 15:36:01 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Sun, 10 Nov 2019 16:36:01 +0100 Subject: Record canonical constructor is required to be public In-Reply-To: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> References: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> Message-ID: <06728659-56EA-44AF-A239-1F5435F770D1@oracle.com> Yes, this is about the fourth time you?ve brought this up... I understand your concerns here (as I?ve said before). We?re not going to do anything about it right now ? and I don?t want to discuss it further until after 14 closes. But, I will put a few points into the record for when that discussion resumes. I understand that it is a little weird that the constructor is public when the class is not. It is a little weird, but in reality, _it makes no difference_. Public doesn?t really mean public, it means ?public, subject to the public-ness of my containing class, and the exported-ness of my containing package.? So this is really just a personal-preference argument, that you find this weirdness more weird than the weirdness introduce by the alternate (and more complex) scheme. I also understand that you are making a ?for consistency? argument with how default constructors work. But, there are more moving parts here, so I don?t find the ?but default constructors work this way? argument to be compelling in this case. What you?re missing is the accessors. A record gains a set of mandated members, which must be accessible. All the talk so far has been about the constructor, but it would be ridiculous to use a different accessibility scheme for the constructor as for the other mandated members. We would have to have the same treatment for all the mandated members (some of which must be public, as they come from Object.) And here?s why this scheme is not without cost. Because the accessors and the constructor can be explicitly specified, now we have a more complex rule about what accessibilities are allowed on explicit members (i.e., it should be OK to upgrade from package to public, but not the other way around). And this is a nontrivial amount of additional spec complexity compared to ?they?re always public.? Further, if one has a package-protected record with explicit members, and one changes the accessibility of the record, one has to change the accessibility of all mandated members. So while your scheme (assuming it encompasses accessors too) may feel cleaner, it is also more expensive for both the spec and for the users, who have to internalize a more complex rule. (Yes, its the same as the default constructor, but: _no one knows this rule_, so we can?t really lean on the ?but its just like something else they understand.?) Which is why it is by no means the slam-dunk you seem to think it is, and why have been unwilling to reopen this issue. We can reconsider it after the first preview. > On Nov 9, 2019, at 2:31 PM, Remi Forax wrote: > > I know we already discuss that but i still don't understand why a canonical constructor has to be public. > > I understand that a canonical constructor is not a simple constructor because it is also used as a kind of default de-constructor, but this doesn't work well with the current rules for constructors in nested classes/enums and if the class is not visible, it's constructor is not visible anyway. > > As Brian said in its presentation at Devoxx, records can be used to represent local nominal tuples, like > > public void foo() { > record Pair(String name, int value); > ... > } > > If one want to add a requireNonNull using a compact constructor, it will be > public void foo() { > record Pair(String name, int value) { > public Pair { > Objects.requireNonNull(name); > } > } > ... > } > > having to declare the constructor to be public in that case seems weird. > > Mandating that the canonical constructor (hence the compact constructor) to be public: > - goes against the idea of encapsulation that a constructor like any members should be the least visible > - goes against the rules of default constructors (default constructor use the same visibility as their class) [1] > - goes against the rules of constructors in enums (use private or package private depending on the kind of enums) [2] > > So we a set of rules in the JLS that follows the idea that a constructor should not be public by default in nested classes [1] but the rule for a canonical constructor doesn't follow the same idea [3], this should be fixed. > > In my opinion, the rule for a canonical constructor should be the same as the rule for a default constructor. > > regards, > R?mi > > > [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9 > [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2 > [3] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 From brian.goetz at oracle.com Sun Nov 10 15:38:53 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Sun, 10 Nov 2019 16:38:53 +0100 Subject: Draft JLS spec for records - local types In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <2452487.ezX9TyzB4F@cube> <4CA095B6-C83D-4F6A-BC09-121469FF5C21@oracle.com> Message-ID: <13DD34E1-387B-434D-85C4-74BC040B6458@oracle.com> Sorry, I know I?ve said this before, but I guess not on this thread. Local records are always implicitly static ? they cannot capture anything. (Local enums would be the same way.) As you point out, the hidden state would undermine the ?the record description is the state, the whole state, and nothing but the state? directive. > On Nov 9, 2019, at 4:31 PM, Tagir Valeev wrote: > > Hello! > >> Local records should be allowed; we should probably allow local enums at the same time. > > On the other hand, local classes also may have an implicit state which > consists of captured variables and possibly captured `this` reference > as well. Usually, all instances of local classes that can interact > with each other have the same captured state, but it's not impossible > to have two instances with the different captured state. E.g.: > > public static void main(String[] args) { > foo(0); > } > > static Object foo(int x) { > class Foo { > int getX() { return x; } > } > if (x == 1) { > return new Foo(); > } > Foo foo1 = new Foo(); > Foo foo2 = (Foo) foo(1); > System.out.println(foo1.getX()); // prints 0 > System.out.println(foo2.getX()); // prints 1 > return null; > } > > If we allow local records, they would also have an implicit state, > that "hidden extra component". E.g. if we define a record without > components instead of class Foo in the example above, its `equals` > method would return true for `foo1` and `foo2`, yet they have > different behavior. Is it still ok? > > With best regards, > Tagir Valeev. From brian.goetz at oracle.com Sun Nov 10 15:43:55 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Sun, 10 Nov 2019 16:43:55 +0100 Subject: [records] Non-compact canonical constructors In-Reply-To: References: Message-ID: > Several points are unclear to me > 1. It's not explicitly specified whether an explicitly declared > canonical constructor must be 'public' like it's specified for compact > constructors. Does this mean that I can declare non-public canonical > constructor? The compact constructor _is_ a canonical constructor; its just an alternate notation for it, and its an error to declare it both ways (because its an error to declare the same member twice). The canonical constructor should be public (yes, Remi, we see you there), whether declared implicitly, explicitly with a full argument list, or explicitly with a compact ctor. > 2. I see the restriction for not having a return statement quite > arbitrary. I understand it for compact constructors but see no reason > for this restriction in non-compact canonical constructors. Could > anybody provide a rationale behind this restriction? Sorry if it was > discussed; in this case, links to the discussion would also be > appreciated. Yes, it exists primarily for compact constructors and could be refined to mention only those. > 3. As it's already mentioned in 8.10.3, each record component implies > an implicitly declared private final field. And as 8.3.1.2 [2] says, > "A blank final instance variable must be definitely assigned and > moreover not definitely unassigned at the end of every constructor of > the class in which it is declared". Thus "Every field corresponding to > a record component of R must be definitely assigned and moreover not > definitely unassigned..." part seems redundant as it's covered by > normal constructor rules. Probably it's not harmful to specify this > explicitly though. Agreed. Ordinary DA should cover this, though its reasonable to remind the reader that DA applies to implicitly declared final fields too. From john.r.rose at oracle.com Sun Nov 10 18:58:18 2019 From: john.r.rose at oracle.com (John Rose) Date: Sun, 10 Nov 2019 10:58:18 -0800 Subject: Record canonical constructor is required to be public In-Reply-To: <06728659-56EA-44AF-A239-1F5435F770D1@oracle.com> References: <06728659-56EA-44AF-A239-1F5435F770D1@oracle.com> Message-ID: <31B97486-614F-48AB-9161-9E0D37CE1FE4@oracle.com> Thanks for spelling that out Brian. I withdraw my earlier +1. > On Nov 10, 2019, at 7:36 AM, Brian Goetz wrote: > > ?Yes, this is about the fourth time you?ve brought this up... > > I understand your concerns here (as I?ve said before). We?re not going to do anything about it right now ? and I don?t want to discuss it further until after 14 closes. But, I will put a few points into the record for when that discussion resumes. > > I understand that it is a little weird that the constructor is public when the class is not. It is a little weird, but in reality, _it makes no difference_. Public doesn?t really mean public, it means ?public, subject to the public-ness of my containing class, and the exported-ness of my containing package.? So this is really just a personal-preference argument, that you find this weirdness more weird than the weirdness introduce by the alternate (and more complex) scheme. > > I also understand that you are making a ?for consistency? argument with how default constructors work. But, there are more moving parts here, so I don?t find the ?but default constructors work this way? argument to be compelling in this case. > > What you?re missing is the accessors. A record gains a set of mandated members, which must be accessible. All the talk so far has been about the constructor, but it would be ridiculous to use a different accessibility scheme for the constructor as for the other mandated members. We would have to have the same treatment for all the mandated members (some of which must be public, as they come from Object.) > > And here?s why this scheme is not without cost. Because the accessors and the constructor can be explicitly specified, now we have a more complex rule about what accessibilities are allowed on explicit members (i.e., it should be OK to upgrade from package to public, but not the other way around). And this is a nontrivial amount of additional spec complexity compared to ?they?re always public.? Further, if one has a package-protected record with explicit members, and one changes the accessibility of the record, one has to change the accessibility of all mandated members. So while your scheme (assuming it encompasses accessors too) may feel cleaner, it is also more expensive for both the spec and for the users, who have to internalize a more complex rule. (Yes, its the same as the default constructor, but: _no one knows this rule_, so we can?t really lean on the ?but its just like something else they understand.?) Which is why it is by no means the slam-dunk you seem to think it is, and why have been unwilling to reopen this issue. > > We can reconsider it after the first preview. > > > > > >> On Nov 9, 2019, at 2:31 PM, Remi Forax wrote: >> >> I know we already discuss that but i still don't understand why a canonical constructor has to be public. >> >> I understand that a canonical constructor is not a simple constructor because it is also used as a kind of default de-constructor, but this doesn't work well with the current rules for constructors in nested classes/enums and if the class is not visible, it's constructor is not visible anyway. >> >> As Brian said in its presentation at Devoxx, records can be used to represent local nominal tuples, like >> >> public void foo() { >> record Pair(String name, int value); >> ... >> } >> >> If one want to add a requireNonNull using a compact constructor, it will be >> public void foo() { >> record Pair(String name, int value) { >> public Pair { >> Objects.requireNonNull(name); >> } >> } >> ... >> } >> >> having to declare the constructor to be public in that case seems weird. >> >> Mandating that the canonical constructor (hence the compact constructor) to be public: >> - goes against the idea of encapsulation that a constructor like any members should be the least visible >> - goes against the rules of default constructors (default constructor use the same visibility as their class) [1] >> - goes against the rules of constructors in enums (use private or package private depending on the kind of enums) [2] >> >> So we a set of rules in the JLS that follows the idea that a constructor should not be public by default in nested classes [1] but the rule for a canonical constructor doesn't follow the same idea [3], this should be fixed. >> >> In my opinion, the rule for a canonical constructor should be the same as the rule for a default constructor. >> >> regards, >> R?mi >> >> >> [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9 >> [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2 >> [3] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 > From forax at univ-mlv.fr Sun Nov 10 20:42:15 2019 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Sun, 10 Nov 2019 21:42:15 +0100 (CET) Subject: Record canonical constructor is required to be public In-Reply-To: <06728659-56EA-44AF-A239-1F5435F770D1@oracle.com> References: <137004642.69145.1573306308846.JavaMail.zimbra@u-pem.fr> <06728659-56EA-44AF-A239-1F5435F770D1@oracle.com> Message-ID: <1791230942.195976.1573418535422.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Brian Goetz" > ?: "Remi Forax" > Cc: "amber-spec-experts" > Envoy?: Dimanche 10 Novembre 2019 16:36:01 > Objet: Re: Record canonical constructor is required to be public > Yes, this is about the fourth time you?ve brought this up... yes, because they have not be a clear answer before. > > I understand your concerns here (as I?ve said before). We?re not going to do > anything about it right now ? and I don?t want to discuss it further until > after 14 closes. But, I will put a few points into the record for when that > discussion resumes. I'm ok with that, but i will just point that the fact that you want to delay the discussion about that subject is new to me, maybe i've missed an email on that subject ? > > I understand that it is a little weird that the constructor is public when the > class is not. It is a little weird, but in reality, _it makes no difference_. > Public doesn?t really mean public, it means ?public, subject to the > public-ness of my containing class, and the exported-ness of my containing > package.? So this is really just a personal-preference argument, that you find > this weirdness more weird than the weirdness introduce by the alternate (and > more complex) scheme. > > I also understand that you are making a ?for consistency? argument with how > default constructors work. But, there are more moving parts here, so I don?t > find the ?but default constructors work this way? argument to be compelling in > this case. > > What you?re missing is the accessors. A record gains a set of mandated members, > which must be accessible. All the talk so far has been about the constructor, > but it would be ridiculous to use a different accessibility scheme for the > constructor as for the other mandated members. We would have to have the same > treatment for all the mandated members (some of which must be public, as they > come from Object.) There are 3 kinds of generated methods, the canonical constructor, accessors and public methods of Object. Obviously, the later are required to be public. > > And here?s why this scheme is not without cost. Because the accessors and the > constructor can be explicitly specified, now we have a more complex rule about > what accessibilities are allowed on explicit members (i.e., it should be OK to > upgrade from package to public, but not the other way around). And this is a > nontrivial amount of additional spec complexity compared to ?they?re always > public.? Further, if one has a package-protected record with explicit members, > and one changes the accessibility of the record, one has to change the > accessibility of all mandated members. So while your scheme (assuming it > encompasses accessors too) may feel cleaner, it is also more expensive for both > the spec and for the users, who have to internalize a more complex rule. (Yes, > its the same as the default constructor, but: _no one knows this rule_, so we > can?t really lean on the ?but its just like something else they understand.?) > Which is why it is by no means the slam-dunk you seem to think it is, and why > have been unwilling to reopen this issue. _no one knows this rule_ is exactly the point of this rule, nobody knows it because it's the right default. So yes, it maybe more complex in term of spec (one more paragraph ?) but it reduce the cognitive complexity for everybody that will want to provide an explicit canonical constructor (or a compact one) or an explicit accessor for a non top level record. > > We can reconsider it after the first preview. no problem with that. R?mi > > > > > >> On Nov 9, 2019, at 2:31 PM, Remi Forax wrote: >> >> I know we already discuss that but i still don't understand why a canonical >> constructor has to be public. >> >> I understand that a canonical constructor is not a simple constructor because it >> is also used as a kind of default de-constructor, but this doesn't work well >> with the current rules for constructors in nested classes/enums and if the >> class is not visible, it's constructor is not visible anyway. >> >> As Brian said in its presentation at Devoxx, records can be used to represent >> local nominal tuples, like >> >> public void foo() { >> record Pair(String name, int value); >> ... >> } >> >> If one want to add a requireNonNull using a compact constructor, it will be >> public void foo() { >> record Pair(String name, int value) { >> public Pair { >> Objects.requireNonNull(name); >> } >> } >> ... >> } >> >> having to declare the constructor to be public in that case seems weird. >> >> Mandating that the canonical constructor (hence the compact constructor) to be >> public: >> - goes against the idea of encapsulation that a constructor like any members >> should be the least visible >> - goes against the rules of default constructors (default constructor use the >> same visibility as their class) [1] >> - goes against the rules of constructors in enums (use private or package >> private depending on the kind of enums) [2] >> >> So we a set of rules in the JLS that follows the idea that a constructor should >> not be public by default in nested classes [1] but the rule for a canonical >> constructor doesn't follow the same idea [3], this should be fixed. >> >> In my opinion, the rule for a canonical constructor should be the same as the >> rule for a default constructor. >> >> regards, >> R?mi >> >> >> [1] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.8.9 >> [2] https://docs.oracle.com/javase/specs/jls/se13/html/jls-8.html#jls-8.9.2 >> [3] > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.4 From gavin.bierman at oracle.com Sun Nov 10 21:32:13 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Sun, 10 Nov 2019 21:32:13 +0000 Subject: Reminder about draft specs In-Reply-To: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> References: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> Message-ID: Chris: Let's try to find some time on Monday to sort out the spec regarding serialisation. Okay? Thanks, Gavin > On 8 Nov 2019, at 17:11, Chris Hegarty wrote: > > Gavin, > >> On 8 Nov 2019, at 15:28, Gavin Bierman > wrote: >> >> ... >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html > Looks good. A comment relating to Serialization, from section 8.10.1 - Record Components. > > As all record types are subclasses of the class java.lang.Record which in turn implements the interface java.io.Serializable, it is necessary to ? > > > This is not true. j.i.Record does not implement Serializable. Not all records are serializable. > > A record may be serializable, if it implements the java.io .Serializable interface, but it is not required. For example, > > record SerializableFoo (int x, int y) implements java.io.Serializable { } > > Additionally, I thought that all serialization related magic members were to be restricted from being record component names ( they are just too odd and potentially confusing ) ? The spec has some, but not all. The complete list ( of 7 ) is: writeObject, readObject, readObjectNoData, writeReplace, readResolve, serialVersionUID, serialPersistentFields. > > -Chris. > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From amaembo at gmail.com Mon Nov 11 03:54:58 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Mon, 11 Nov 2019 10:54:58 +0700 Subject: Draft JLS spec for records - local types In-Reply-To: <13DD34E1-387B-434D-85C4-74BC040B6458@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <2452487.ezX9TyzB4F@cube> <4CA095B6-C83D-4F6A-BC09-121469FF5C21@oracle.com> <13DD34E1-387B-434D-85C4-74BC040B6458@oracle.com> Message-ID: > Sorry, I know I?ve said this before, but I guess not on this thread. Local records are always implicitly static ? they cannot capture anything. (Local enums would be the same way.) As you point out, the hidden state would undermine the ?the record description is the state, the whole state, and nothing but the state? directive. Thank you for the explanation. I saw this wording in the spec draft [1] but it sounds unclear, at least to me. We never had local static classes, so I'm not sure that "implicitly static" is enough explanation for "they cannot capture anything". Another unclear item is whether they can use compile-time constants that refer to surrounding local variables. E.g.: public static void main(String[] args) { final double TWO_PI = Math.PI * 2; record Circle(Point center, double radius) { double circumference() { return TWO_PI * radius; // allowed? } } } So I think this part of the spec should be more verbose, probably including some examples. I expect a wording like this: "It's a compile-time error if a local record refers to a local variable or parameter declared outside of the record, except (or including) compile-time constants" With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-14.3 From amaembo at gmail.com Mon Nov 11 04:07:51 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Mon, 11 Nov 2019 11:07:51 +0700 Subject: [records] Non-compact canonical constructors In-Reply-To: References: Message-ID: Hello! > > Several points are unclear to me > > 1. It's not explicitly specified whether an explicitly declared > > canonical constructor must be 'public' like it's specified for compact > > constructors. Does this mean that I can declare non-public canonical > > constructor? > > The compact constructor _is_ a canonical constructor; its just an alternate notation for it, and its an error to declare it both ways (because its an error to declare the same member twice). The canonical constructor should be public (yes, Remi, we see you there), whether declared implicitly, explicitly with a full argument list, or explicitly with a compact ctor. Sure, this sounds consistent. I'm just saying that this part of the current spec draft is incomplete. It says that implicit canonical ctor is public; it says that compact ctor must be public but it says nothing about explicit canonical ctor. And it's not evident that it must be the same as in the implicit declaration (e.g. implicit default ctor has the same access level as the class, but explicit one is allowed to have the different one). Also, compact constructor rules should not be taken into account for the explicit canonical constructor: the compact constructor is a partial case, so it could be more restrictive. My suggestion is to write this explicitly in 8.10.4: If the canonical constructor is explicitly declared, then it must satisfy the following; otherwise a compile-time error occurs: - The canonical constructor must be declared public. ... > > 2. I see the restriction for not having a return statement quite > > arbitrary. I understand it for compact constructors but see no reason > > for this restriction in non-compact canonical constructors. Could > > anybody provide a rationale behind this restriction? Sorry if it was > > discussed; in this case, links to the discussion would also be > > appreciated. > > Yes, it exists primarily for compact constructors and could be refined to mention only those. Great. > > 3. As it's already mentioned in 8.10.3, each record component implies > > an implicitly declared private final field. And as 8.3.1.2 [2] says, > > "A blank final instance variable must be definitely assigned and > > moreover not definitely unassigned at the end of every constructor of > > the class in which it is declared". Thus "Every field corresponding to > > a record component of R must be definitely assigned and moreover not > > definitely unassigned..." part seems redundant as it's covered by > > normal constructor rules. Probably it's not harmful to specify this > > explicitly though. > > Agreed. Ordinary DA should cover this, though its reasonable to remind the reader that DA applies to implicitly declared final fields too. > So to summarize, my suggestion is to reformulate this part of 8.10.4, as follows: If the canonical constructor is explicitly declared, then it must satisfy the following; otherwise a compile-time error occurs: - The canonical constructor must be declared public. - The body of a canonical constructor must not contain an explicit constructor invocation statement (8.8.7.1). - Every field corresponding to a record component of R must be definitely assigned and moreover not definitely unassigned (16.9) at the end of the canonical constructor. // or probably remove this item - All the other rules for a constructor in a normal class declaration must be satisfied (8.8). And for compact constructor (8.10.5): A compact constructor declaration must satisfy all of the following conditions; otherwise a compile-time error occurs. - The compact constructor must be declared public. - The body of a compact constructor must not contain an explicit constructor invocation statement (8.8.7.1). - The body of a compact constructor must not contain a return statement (14.17). - All the other rules for a constructor in a normal class declaration must be satisfied (8.8). With best regards, Tagir Valeev. From manoj.palat at in.ibm.com Mon Nov 11 06:49:37 2019 From: manoj.palat at in.ibm.com (Manoj Palat) Date: Mon, 11 Nov 2019 06:49:37 +0000 Subject: New candidate JEP: 361: Switch Expressions (Standard) In-Reply-To: References: , <20190925223215.EDE103084E1@eggemoggin.niobe.net> <7E8C18C5-726B-4F2C-9F3B-AC386CC97B82@oracle.com> Message-ID: An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Tue Nov 12 15:36:09 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 12 Nov 2019 07:36:09 -0800 Subject: [records] Non-compact canonical constructors In-Reply-To: References: Message-ID: <01fb22b3-7869-055e-39c7-fe5f302b8a5d@oracle.com> On 11/10/2019 8:07 PM, Tagir Valeev wrote: >>> 1. It's not explicitly specified whether an explicitly declared >>> canonical constructor must be 'public' like it's specified for >>> compact constructors. Does this mean that I can declare >>> non-public canonical constructor? >> >> The compact constructor _is_ a canonical constructor; its just an >> alternate notation for it, and its an error to declare it both >> ways (because its an error to declare the same member twice). The >> canonical constructor should be public (yes, Remi, we see you >> there), whether declared implicitly, explicitly with a full >> argument list, or explicitly with a compact ctor. > > Sure, this sounds consistent. I'm just saying that this part of the > current spec draft is incomplete. Yes, this was the issue @ https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-November/001760.html and https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-November/001761.html -- there is a slight misfactoring in how an explicitly declared canonical ctor is specified. Alex From chris.hegarty at oracle.com Tue Nov 12 17:05:30 2019 From: chris.hegarty at oracle.com (Chris Hegarty) Date: Tue, 12 Nov 2019 17:05:30 +0000 Subject: Reminder about draft specs In-Reply-To: References: <8B483023-4346-464C-AF68-94B1FA6722C6@oracle.com> Message-ID: <7D444563-9263-49F4-93B5-04025E543B16@oracle.com> > On 9 Nov 2019, at 04:57, John Rose wrote: > > I like the (de-)serialization specification for records, because it is a minimum cut on the existing > specification. A day may come when a new serialization is based on something like expression > trees which are executed to produce the deserialized values? but it is not THIS day, as Aragorn > might say. > > In order to emphasize the incremental relation of record serialization to what has gone before, > it would be helpful (even if only as a blog post) to show how the effect of record serialization, > as documented in the proposed spec., would look if it were hand-coded using today?s > serialization. > > I guess what I?m saying is that records can be demystified if they can be (as much as possible) > described in terms of the boilerplate you would be forced to write, if you wanted the proposed > behavior, but didn?t have the proposed feature. Make sense? Yes, good idea. I?ll write something up. -Chris. From forax at univ-mlv.fr Wed Nov 13 15:52:20 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 13 Nov 2019 16:52:20 +0100 (CET) Subject: final fields in record Message-ID: <1061128754.992811.1573660340416.JavaMail.zimbra@u-pem.fr> It occurs to me that given that record is a new construct, we can fix an error from the past [1], final field not really be final. Obviouly, it means that refactoring a class to a record or vice-versa will not be 100% compatible, but given that we have already introduced Class.isRecord(), it's not 100% compatible anyway. Compared to [1], which aim to solve the problem by adding more metadata, disabling mutation of the record synthetic fields once for all has the advantages that it requires less memory (and less possible deopt). Given that records are immutable and that there is a special mechanism to deserialize them, it think we should disallow records synthetic fields to be changed at runtime using reflection, JNI, Unsafe etc. I believe the JLS has to be updated a bit to explicitly says that you can not change the synthetic fields of a record even by reflection during deserialization, the reflection Field.set() has to be amended, etc. And in the VM, the function `trust_final_non_static_fields` should add a case to trust record fields. regards, R?mi [1] https://bugs.openjdk.java.net/browse/JDK-8233873 From brian.goetz at oracle.com Wed Nov 13 16:50:20 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 13 Nov 2019 16:50:20 +0000 Subject: final fields in record In-Reply-To: <1061128754.992811.1573660340416.JavaMail.zimbra@u-pem.fr> References: <1061128754.992811.1573660340416.JavaMail.zimbra@u-pem.fr> Message-ID: As much as I detest that there are various ways to write final fields, I do not think that trying to key off of records to prevent this has the right return-on-complexity. (Perhaps different story for values). Sent from my MacBook Wheel > On Nov 13, 2019, at 3:52 PM, Remi Forax wrote: > > ?It occurs to me that given that record is a new construct, we can fix an error from the past [1], final field not really be final. > > Obviouly, it means that refactoring a class to a record or vice-versa will not be 100% compatible, but given that we have already introduced Class.isRecord(), it's not 100% compatible anyway. Compared to [1], which aim to solve the problem by adding more metadata, disabling mutation of the record synthetic fields once for all has the advantages that it requires less memory (and less possible deopt). > > Given that records are immutable and that there is a special mechanism to deserialize them, > it think we should disallow records synthetic fields to be changed at runtime using reflection, JNI, Unsafe etc. > > I believe the JLS has to be updated a bit to explicitly says that you can not change the synthetic fields of a record even by reflection during deserialization, > the reflection Field.set() has to be amended, etc. > > And in the VM, the function `trust_final_non_static_fields` should add a case to trust record fields. > > regards, > R?mi > > [1] https://bugs.openjdk.java.net/browse/JDK-8233873 From forax at univ-mlv.fr Fri Nov 15 07:17:23 2019 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 15 Nov 2019 08:17:23 +0100 (CET) Subject: final fields in record In-Reply-To: References: <1061128754.992811.1573660340416.JavaMail.zimbra@u-pem.fr> Message-ID: <225451956.1598101.1573802243949.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Brian Goetz" > ?: "Remi Forax" > Cc: "amber-spec-experts" > Envoy?: Mercredi 13 Novembre 2019 17:50:20 > Objet: Re: final fields in record > As much as I detest that there are various ways to write final fields, I do not > think that trying to key off of records to prevent this has the right > return-on-complexity. (Perhaps different story for values). the idea was more to single out the plain old class, by an accident of the history, enum fields can be non final but hidden class (and its non public counterpart VM anonymous class) and inline class already have their final fields as really final. R?mi > > Sent from my MacBook Wheel > >> On Nov 13, 2019, at 3:52 PM, Remi Forax wrote: >> >> ?It occurs to me that given that record is a new construct, we can fix an error >> ?from the past [1], final field not really be final. >> >> Obviouly, it means that refactoring a class to a record or vice-versa will not >> be 100% compatible, but given that we have already introduced Class.isRecord(), >> it's not 100% compatible anyway. Compared to [1], which aim to solve the >> problem by adding more metadata, disabling mutation of the record synthetic >> fields once for all has the advantages that it requires less memory (and less >> possible deopt). >> >> Given that records are immutable and that there is a special mechanism to >> deserialize them, >> it think we should disallow records synthetic fields to be changed at runtime >> using reflection, JNI, Unsafe etc. >> >> I believe the JLS has to be updated a bit to explicitly says that you can not >> change the synthetic fields of a record even by reflection during >> deserialization, >> the reflection Field.set() has to be amended, etc. >> >> And in the VM, the function `trust_final_non_static_fields` should add a case to >> trust record fields. >> >> regards, >> R?mi >> > > [1] https://bugs.openjdk.java.net/browse/JDK-8233873 From gavin.bierman at oracle.com Fri Nov 15 15:22:15 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 15 Nov 2019 15:22:15 +0000 Subject: [records] Non-compact canonical constructors In-Reply-To: References: Message-ID: Thanks Tagir. > On 11 Nov 2019, at 04:07, Tagir Valeev wrote: > > Hello! > >>> Several points are unclear to me >>> 1. It's not explicitly specified whether an explicitly declared >>> canonical constructor must be 'public' like it's specified for compact >>> constructors. Does this mean that I can declare non-public canonical >>> constructor? >> >> The compact constructor _is_ a canonical constructor; its just an alternate notation for it, and its an error to declare it both ways (because its an error to declare the same member twice). The canonical constructor should be public (yes, Remi, we see you there), whether declared implicitly, explicitly with a full argument list, or explicitly with a compact ctor. > > Sure, this sounds consistent. I'm just saying that this part of the > current spec draft is incomplete. It says that implicit canonical ctor > is public; it says that compact ctor must be public but it says > nothing about explicit canonical ctor. And it's not evident that it > must be the same as in the implicit declaration (e.g. implicit default > ctor has the same access level as the class, but explicit one is > allowed to have the different one). Also, compact constructor rules > should not be taken into account for the explicit canonical > constructor: the compact constructor is a partial case, so it could be > more restrictive. My suggestion is to write this explicitly in 8.10.4: > > If the canonical constructor is explicitly declared, then it must > satisfy the following; otherwise a compile-time error occurs: > - The canonical constructor must be declared public. Agreed. > ... > >>> 2. I see the restriction for not having a return statement quite >>> arbitrary. I understand it for compact constructors but see no reason >>> for this restriction in non-compact canonical constructors. Could >>> anybody provide a rationale behind this restriction? Sorry if it was >>> discussed; in this case, links to the discussion would also be >>> appreciated. >> >> Yes, it exists primarily for compact constructors and could be refined to mention only those. > > Great. > >>> 3. As it's already mentioned in 8.10.3, each record component implies >>> an implicitly declared private final field. And as 8.3.1.2 [2] says, >>> "A blank final instance variable must be definitely assigned and >>> moreover not definitely unassigned at the end of every constructor of >>> the class in which it is declared". Thus "Every field corresponding to >>> a record component of R must be definitely assigned and moreover not >>> definitely unassigned..." part seems redundant as it's covered by >>> normal constructor rules. Probably it's not harmful to specify this >>> explicitly though. >> >> Agreed. Ordinary DA should cover this, though its reasonable to remind the reader that DA applies to implicitly declared final fields too. >> > > So to summarize, my suggestion is to reformulate this part of 8.10.4, > as follows: > > If the canonical constructor is explicitly declared, then it must > satisfy the following; otherwise a compile-time error occurs: > - The canonical constructor must be declared public. > - The body of a canonical constructor must not contain an explicit > constructor invocation statement (8.8.7.1). > - Every field corresponding to a record component of R must be > definitely assigned and > moreover not definitely unassigned (16.9) at the end of the canonical > constructor. // or probably remove this item > - All the other rules for a constructor in a normal class declaration > must be satisfied (8.8). I think we should remove the third item. It?s not needed. > > And for compact constructor (8.10.5): > > A compact constructor declaration must satisfy all of the following > conditions; otherwise a compile-time error occurs. > - The compact constructor must be declared public. > - The body of a compact constructor must not contain an explicit > constructor invocation statement (8.8.7.1). > - The body of a compact constructor must not contain a return statement (14.17). > - All the other rules for a constructor in a normal class declaration > must be satisfied (8.8). Agreed. > > With best regards, > Tagir Valeev. From gavin.bierman at oracle.com Fri Nov 15 15:40:39 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 15 Nov 2019 15:40:39 +0000 Subject: [records] Compact constructor type parameters In-Reply-To: <567B63C0-7987-4AB8-AA8B-3342B5F1C488@oracle.com> References: <567B63C0-7987-4AB8-AA8B-3342B5F1C488@oracle.com> Message-ID: <80FE7575-F7BD-4C86-A796-D3C9E6D0A94F@oracle.com> Sounds good. Gavin > On 9 Nov 2019, at 11:47, Brian Goetz wrote: > > This is reasonable and probably easy to spec: when we define the canonical ctor, in addition to defining its is defined to have no type parameters. Since the compact ctor is shorthand for a full canonical ctor, no additional spec is needed for that. > > Sent from my iPad > >> On Nov 9, 2019, at 12:07 PM, Tagir Valeev wrote: >> >> Hello! >> >> Reading the latest JLS spec draft for records, chapter 8.10.5 [1] I >> see the following: >> >> A compact constructor declaration provides an alternative, succinct >> means to declare a canonical constructor for a record type. >> CompactConstructorDeclaration:{ Annotation } { ConstructorModifier } [ >> TypeParameters ] SimpleTypeName ConstructorBody >> >> Is it really useful to allow type parameters specification for a >> compact constructor, given that we cannot alter the formal parameters >> list, thus we cannot use them there? Yes, we could use them to declare >> local variables but this is an implementation detail, thus it should >> not leak to the clients (especially given the fact that canonical >> constructors are always public). Should not we exclude type parameters >> from the compact constructor declaration? >> >> I think we can go even further and disable type parameters for >> explicit canonical constructor declaration (not in compact form) as >> well. WDYT? >> >> With best regards, >> Tagir Valeev. >> >> [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.5 > From gavin.bierman at oracle.com Fri Nov 15 16:20:55 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 15 Nov 2019 16:20:55 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> Message-ID: <1C328D49-E29A-424A-8D08-A6F0EBA569F3@oracle.com> Thanks Maurizio > On 31 Oct 2019, at 14:29, Maurizio Cimadamore wrote: > > Related to the earlier discussion on forbidden record members - how is this section still relevant? > > "It is a compile-time error for a record declaration to declare a record component with the name clone, finalize, getClass, hashCode, notify, notifyAll, readObjectNoData, readResolve, serialPersistentFields, serialVersionUID, toString, wait, or writeReplace." > > Chris says that the serialization spec ignores all the serialization-related methods if they appear inside a record; should we lift the restrictions? Yes, we?re going to update this part of the spec. I will write separately about this. > > In the grammar for records, I find it odd that we basically say that record members are class members plus compact constructor, but then we revert to say that instance initializer are not allowed. > I wonder if a more specific production for the record body would be useful and more direct here? I think this is a style thing, but I?m keen to reuse the class grammar. > > I note an asymmetry between the rules for canonical constructor and compact constructor; in one we say: > > "Every field corresponding to a record component of R must be definitely assigned and moreover not definitely unassigned (16.9) at the end of the body of the canonical constructor." > > In the other we say: > > "It is a compile-time error if at the end of the body of the compact constructor, any of the fields corresponding to the record components of R are neither definitely assigned nor definitely unassigned.? Indeed. Although I can remove both as we get this by virtue of the fields being blank final instance variables (JLS 8.3.1.2). > > Moreover, a deeper question: should we leave the magic auto-initialization of fields only for the compact form? That way, you would have a _new_ linguistic form, with _new_ properties, whereas old forms (e.g. a constructor with parameters) will have same rules as before (can have returns, must initialize fields explicitly). I think that, from a pedagogical aspect, that would be preferrable. That?s what we do. Thanks, Gavin -------------- next part -------------- An HTML attachment was scrubbed... URL: From gavin.bierman at oracle.com Fri Nov 15 16:22:35 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 15 Nov 2019 16:22:35 +0000 Subject: New candidate JEP: 361: Switch Expressions (Standard) In-Reply-To: References: <20190925223215.EDE103084E1@eggemoggin.niobe.net> <7E8C18C5-726B-4F2C-9F3B-AC386CC97B82@oracle.com> Message-ID: <6C67C8FC-935F-4E13-A618-FC268D607F74@oracle.com> Great news! Thanks, Gavin > On 11 Nov 2019, at 06:49, Manoj Palat wrote: > > Hi Gavin, > > For the record, JEP 361 Switch Expressions draft looks fine - we have started to make the preview-to-standard transition of Switch Expressions in Eclipse on the basis of this, already. > > Thanks, > Manoj > Eclipse Java Dev, IBM. > > ----- Original message ----- > From: Gavin Bierman > Sent by: "amber-spec-experts" > To: amber-spec-experts > Cc: amber-dev , Jan Lahoda > Subject: [EXTERNAL] Re: New candidate JEP: 361: Switch Expressions (Standard) > Date: Mon, Oct 21, 2019 4:54 PM > > Just a gentle reminder if you have any feedback based on your experience with using this feature. > > Gavin > >> >> On 27 Sep 2019, at 17:45, Gavin Bierman > wrote: >> >> Please note that we are considering making this a permanent feature, so this is your last chance to provide substantive feedback based on any new experience you may have had with this feature. >> >> A new, draft language spec for JEP 361 (Switch Expressions) is available at: >> >> >> http://cr.openjdk.java.net/~gbierman/jep361/jep361-20190927/specs/switch-expressions-jls.html >> >> This is identical to the version made available for JEP354, apart from some cosmetic changes around terminology following some feedback. >> >> [For spec nerds: The primary change is that what was previously called a "switch labeled rule" is now called, more simply, a "switch rule?. ?Switch labeled expression? is now a ?switch rule expression?, ?switch labeled block? is now a ?switch rule block? and a ?switch labeled throw statement? is now a ?switch rule throw statement?.] >> >> All feedback welcomed! >> Gavin >> >>> >>> On 25 Sep 2019, at 23:32, mark.reinhold at oracle.com wrote: >>> >>> https://openjdk.java.net/jeps/361 >>> >>> - Mark > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From john.r.rose at oracle.com Fri Nov 15 22:31:41 2019 From: john.r.rose at oracle.com (John Rose) Date: Fri, 15 Nov 2019 14:31:41 -0800 Subject: final fields in record In-Reply-To: <225451956.1598101.1573802243949.JavaMail.zimbra@u-pem.fr> References: <1061128754.992811.1573660340416.JavaMail.zimbra@u-pem.fr> <225451956.1598101.1573802243949.JavaMail.zimbra@u-pem.fr> Message-ID: On Nov 14, 2019, at 11:17 PM, forax at univ-mlv.fr wrote: > > the idea was more to single out the plain old class, > by an accident of the history, enum fields can be non final but hidden class (and its non public counterpart VM anonymous class) and inline class already have their final fields as really final. The time is coming, I hope, to fix this more generally. That way we can remove the tricky stratification. See https://bugs.openjdk.java.net/browse/JDK-8233873 and recent traffic on hotspot-compile-dev at ojn. -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Sun Nov 17 23:39:01 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Sun, 17 Nov 2019 18:39:01 -0500 Subject: Feedback on Sealed Types In-Reply-To: References: <7a3cd179-1ccc-f3d5-b438-3146e87fa4eb@oracle.com> <2005472563.509550.1556713960688.JavaMail.zimbra@u-pem.fr> <8B333F6F-77A8-4571-BA5E-A131A5DD8368@oracle.com> <3CE5AD07-CFCA-47A0-A48A-34E0C3DF0742@oracle.com> Message-ID: <60763484-d752-b830-9f2a-ba1a09612794@oracle.com> And, look what just showed up across the street: https://github.com/dotnet/csharplang/blob/master/proposals/discriminated-unions.md On 5/1/2019 11:34 AM, Alan Malloy wrote: > Yes, that is what I suggest. Two points, though. > > First, the sugar benefit is at least a tiny bit larger than you > say.?You also get to omit instances of if the interface is > parameterized, as I expect it will often be. I argue you should get to > omit public, too: the implementations of a sum should always be > public, just as the accessors for a record should be, for the same > reason: they are the entire propose of defining the type, and allowing > variation here detracts from their semantic value. > > And second, I don't know that counting the number of saved > characters/tokens is the best way to measure the benefits anyway. An > enhanced for loop over an array is not that much shorter than an > old-style for loop with an explicit index - in fact it probably saves > fewer characters than a couple "implements FooSum". But it's clearly a > win because it communicates intent better, and leaves fewer > opportunities to make a mistake, either in writing the code or in > reading it. Likewise the ability to say in a single token, "this is a > closed sum" has legibility benefits aside from just being shorter. > > On Wed, May 1, 2019, 6:58 AM Brian Goetz > wrote: > > > >> >>> I kind a like the intellectual separation between >>> - a sealed interface which represent a closed type and requires >>> a permit clause and >>> - an enum interface which represent a sum type which is sugar on >>> top of sealed interface + records. >> > > To be clear, I think what Alan is suggesting, and what Remi is > supporting, is: > > ?- Make ?sealed? the primitive for defining closed types, as > originally proposed, and also > ?- Make the following > > enumerated interface Foo { > ? ? R(X), S(Y); > > ? ? STUFF > } > > sugar for > > sealed interface Foo > ? ? permits R, S { > > ? ? STUFF > > ? ? record R(X) implements Foo { } > ? ? record S(Y) implements Foo { } > } > > Is that correct? > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Mon Nov 18 08:55:58 2019 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 18 Nov 2019 09:55:58 +0100 (CET) Subject: Feedback on Sealed Types In-Reply-To: <60763484-d752-b830-9f2a-ba1a09612794@oracle.com> References: <7a3cd179-1ccc-f3d5-b438-3146e87fa4eb@oracle.com> <2005472563.509550.1556713960688.JavaMail.zimbra@u-pem.fr> <8B333F6F-77A8-4571-BA5E-A131A5DD8368@oracle.com> <3CE5AD07-CFCA-47A0-A48A-34E0C3DF0742@oracle.com> <60763484-d752-b830-9f2a-ba1a09612794@oracle.com> Message-ID: <2067315301.103145.1574067358171.JavaMail.zimbra@u-pem.fr> yeah, real sum type ! at the same time, i'm already seeing the question what is the difference between an enum and an enum class trending on stackoverflow. R?mi > De: "Brian Goetz" > ?: "Alan Malloy" > Cc: "Remi Forax" , "amber-spec-experts" > > Envoy?: Lundi 18 Novembre 2019 00:39:01 > Objet: Re: Feedback on Sealed Types > And, look what just showed up across the street: > [ > https://github.com/dotnet/csharplang/blob/master/proposals/discriminated-unions.md > | > https://github.com/dotnet/csharplang/blob/master/proposals/discriminated-unions.md > ] > On 5/1/2019 11:34 AM, Alan Malloy wrote: >> Yes, that is what I suggest. Two points, though. >> First, the sugar benefit is at least a tiny bit larger than you say. You also >> get to omit instances of if the interface is parameterized, as I expect >> it will often be. I argue you should get to omit public, too: the >> implementations of a sum should always be public, just as the accessors for a >> record should be, for the same reason: they are the entire propose of defining >> the type, and allowing variation here detracts from their semantic value. >> And second, I don't know that counting the number of saved characters/tokens is >> the best way to measure the benefits anyway. An enhanced for loop over an array >> is not that much shorter than an old-style for loop with an explicit index - in >> fact it probably saves fewer characters than a couple "implements FooSum". But >> it's clearly a win because it communicates intent better, and leaves fewer >> opportunities to make a mistake, either in writing the code or in reading it. >> Likewise the ability to say in a single token, "this is a closed sum" has >> legibility benefits aside from just being shorter. >> On Wed, May 1, 2019, 6:58 AM Brian Goetz < [ mailto:brian.goetz at oracle.com | >> brian.goetz at oracle.com ] > wrote: >>>>> I kind a like the intellectual separation between >>>>> - a sealed interface which represent a closed type and requires a permit clause >>>>> and >>>>> - an enum interface which represent a sum type which is sugar on top of sealed >>>>> interface + records. >>> To be clear, I think what Alan is suggesting, and what Remi is supporting, is: >>> - Make ?sealed? the primitive for defining closed types, as originally proposed, >>> and also >>> - Make the following >>> enumerated interface Foo { >>> R(X), S(Y); >>> STUFF >>> } >>> sugar for >>> sealed interface Foo >>> permits R, S { >>> STUFF >>> record R(X) implements Foo { } >>> record S(Y) implements Foo { } >>> } >>> Is that correct? -------------- next part -------------- An HTML attachment was scrubbed... URL: From gavin.bierman at oracle.com Thu Nov 21 15:01:59 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Thu, 21 Nov 2019 15:01:59 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> Message-ID: <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> A hopefully final draft language spec for JEP 359 (Records) is available at: http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. As always - any further comments/thoughts/bugs most welcome! Gavin > On 31 Oct 2019, at 14:17, Gavin Bierman wrote: > > An updated draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html > > (Alongside is a draft JVM spec for this feature: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html > > ) > > As always, please email me any comments/thoughts/bugs. > > Thanks, > Gavin > > >> On 23 Aug 2019, at 22:25, Gavin Bierman > wrote: >> >> A draft language spec for records is available at: >> >> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >> >> This spec doesn?t yet discuss varargs records - to appear in the next draft. >> >> All comments welcomed! >> >> Thanks, >> Gavin > -------------- next part -------------- An HTML attachment was scrubbed... URL: From maurizio.cimadamore at oracle.com Thu Nov 21 16:23:03 2019 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 21 Nov 2019 16:23:03 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: <2b1b1751-ef42-9619-50a6-e10ddfbea6da@oracle.com> Hi Gavin, looks great - some minor comments: * I'm having problem parsing this sentence "An explicitly declared accessor method is not annotated with any applicable annotation that appears on the corresponding record component." What do you mean exactly? I guess you mean that the explicit accessor does not implicitly get from the components (e.g. you have to restate them)? * when you speak of explicit canonical constructor, I see this: "The body of the canonical constructor must not contain a return statement (14.17)." Why do we have this restriction? After all, as with any other constructor, the language/compiler will ensure that, at the point of 'return' all final fields have been assigned, no? * "If a record type R declares constructors other than the canonical constructor" I think it would be better to rephrase in term of "constructor that is not override-equivalent with canonical constructor" - the term 'other' is vague. Also, override equivalence takes into consideration cases like these: record Foo(List ls) { ??? Foo(List ls) { } //am I canonical? } Typically we allow such moves - for instance there could be clients of the record class which might need a looser signature for compatibility reason. Same should hold for accessors - e.g. interface RawGetter { ?? List list(); } class ListHolder(List list) implements RawGetter { } //is this legal? In other words: * having a more-specific accessor/constructor parameter type (e.g. List) where the component is raw (e.g. List) should always be ok * having a less-specific accessor/constructor parameter type (e.g. List) where the component is generic (e.g. List) could be allowed with unchecked warnings (as we do for override) Maurizio On 21/11/2019 15:01, Gavin Bierman wrote: > A hopefully final draft language spec for JEP 359 (Records) is > available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html > > > This incorporates (I hope!) all the very helpful suggestions from > everyone on these lists - many thanks. > > As always - any further comments/thoughts/bugs most welcome! > > Gavin > >> On 31 Oct 2019, at 14:17, Gavin Bierman > > wrote: >> >> An updated draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >> >> (Alongside is a draft JVM spec for this feature: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >> >> ) >> >> As always, please email me any comments/thoughts/bugs. >> >> Thanks, >> Gavin >> >> >>> On 23 Aug 2019, at 22:25, Gavin Bierman >> > wrote: >>> >>> A draft language spec for records is available at: >>> >>> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >>> >>> This spec doesn?t yet discuss varargs records - to appear in the >>> next draft. >>> >>> All comments welcomed! >>> >>> Thanks, >>> Gavin >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From alex.buckley at oracle.com Thu Nov 21 20:24:29 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 21 Nov 2019 12:24:29 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: <18c56396-b29f-5c51-94fd-6adfe4e0cd7a@oracle.com> On 11/21/2019 7:01 AM, Gavin Bierman wrote: > A hopefully final draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html > > This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. 1. 8.10.1 says "As a record component corresponds to an accessor method, restrictions on accessor methods (8.10.3) mean that it is always a compile-time error for a record header to declare a record component with the name finalize, getClass, hashCode, notify, notifyAll, or toString." -- `record Foo(int wait){}` is also in error because 8.10.3 will see that the imp.decl. accessor method `int wait()` is override-equivalent with the non-private method `void wait()` in Object. Similarly for `record Bar(Object clone){}`. `equals` is a different story, and that's a surprise, so explain it -- show `record Quux(boolean equals){}` as legal because the accessor method is `public boolean equals()` which merely (albeit rather confusingly) overloads the inherited `public boolean equals(Object)` method. The relationship between each of Object's methods and the implicit record components should be spelled out explicitly in the note. 2. 8.10.3: Technical rewording: from "The implicitly declared accessor method is annotated with the annotation that appears on the corresponding record component, if this annotation type is applicable to a method declaration or type context." to "The implicitly declared accessor method is annotated with the annotations, if any, that appear on the corresponding record component and whose annotation types are applicable in the method declaration context or in type contexts or both. Note: This means that an annotation on a record component may not necessarily be carried over to the corresponding implicitly declared accessor method." 3. 8.10.4: A canonical ctor is defined as a public ctor, and then there's an error if an explicit canonical ctor is not public. That error will never occur because a canonical ctor is always public. This was the discussion on November 4, which doesn't seem to have been considered. I think "It is a compile-time error if a record declaration contains more than one explicit declaration of the canonical constructor." is the catch-all solution, but then the JLS must explain in a note why THE canonical ctor can have multiple declarations. 4. 8.10.4: Technical rewording: from "The canonical constructor must not declare type variables." to "The canonical constructor must not be generic (8.8.4)." I assume the November JVMS draft at http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jvms.html is still being updated? Alex From leonid.kuskov at oracle.com Fri Nov 22 19:22:36 2019 From: leonid.kuskov at oracle.com (Leonid Kuskov) Date: Fri, 22 Nov 2019 11:22:36 -0800 Subject: Spec: ACC_MANDATED Message-ID: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> Hi all, The draft JVM spec for JEP 359(Records)* states in chapter 4.7.8 that: "The|Synthetic|attribute is a fixed-length attribute in the|attributes|table of a|ClassFile|,|field_info|, or|method_info|structure (4.1 ,4.5 ,4.6 ). A class member that does not appear in the source code must be marked using a|Synthetic|attribute, or else it must have its|ACC_SYNTHETIC|flag set. The only exceptions to this requirement are compiler-generated methods which are not considered implementation artifacts, namely the instance initialization method representing a default constructor of the Java programming language (2.9.1 ), the class or interface initialization method (2.9.2 ), andthe|Enum.values()|and|Enum.valueOf()|methods*mandated members of enums and records*." So specification allows RI? to mark final fields associated with components and some methods by ACC_MANDATED flag (0x8000). The latest JVMS specification (https://docs.oracle.com/javase/specs/jvms/se13/html/index.html) permits this flag only for 2 attributes: MethodParameters_attribute, Module_attribute . The flag is not mentioned in both tables: Table 4.5-A. "Field access and property flags", Table 4.6-A. "Method access and property flags". From my point of view, usage of this flag with methods/fields contradicts the assertions: >> All bits of the access_flags item not assigned in Table 4.5-A are reserved for future use. *They should be* *set to zero* in generated class files and should be ignored by Java Virtual Machine implementations. >> All bits of the access_flags item not assigned in Table 4.6-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations. Does it make sense to add a definition of ACC_MANDATED to the tables? And: Earlier the spec stated that the Enum.values() and Enum.valueOf() are exceptions to the requirement that a class member that does not appear in the source code must be marked using a Synthetic attribute, or have its ACC_SYNTHETIC flag set. Now names of methods are removed and the more loose statement "mandated members of enums and records" is used. Does it mean that spec won't enumerate "mandated" methods anymore? And the setting of this flag will be implementation-specific? From my point of view, it might break the unambiguity of the signature tests. Should the JCK signature test take into account the ACC_MANDATED flag? Thanks, Leonid *) http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Fri Nov 22 20:02:23 2019 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 22 Nov 2019 13:02:23 -0700 Subject: Spec: ACC_MANDATED In-Reply-To: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> Message-ID: <3507F393-49FC-4FF0-ADAA-343E5277682E@oracle.com> > On Nov 22, 2019, at 12:22 PM, Leonid Kuskov wrote: > > So specification allows RI to mark final fields associated with components and some methods by ACC_MANDATED flag (0x8000). The latest JVMS specification (https://docs.oracle.com/javase/specs/jvms/se13/html/index.html) permits this flag only for 2 attributes: MethodParameters_attribute, Module_attribute . The flag is not mentioned in both tables: Table 4.5-A. "Field access and property flags", Table 4.6-A. "Method access and property flags". > Does it make sense to add a definition of ACC_MANDATED to the tables? To clarify: are you saying javac is using the 0x8000 flags on fields and methods, despite this flag being undefined in these contexts? Or are you saying that you think we should *start* using the flag on fields and methods, with supporting changes to the spec? (The first would be a bug, the second would be a minor new feature.) > Now names of methods are removed and the more loose statement "mandated members of enums and records" is used. Does it mean that spec won't enumerate "mandated" methods anymore? And the setting of this flag will be implementation-specific? From my point of view, it might break the unambiguity of the signature tests. I don't like putting highly specific compilation details in the JVMS description of an attribute. I don't think it's the appropriate place for those kinds of rules. I *do* think we have a reasonable definition of "mandated" based on the specification of the flag, combined with what the JLS has to say about implicit declarations (see, for example, JLS 8.9.3). (JLS doesn't use that particular term, so depending on the answer to your first question, maybe it makes sense to rephrase this rule to talk about "implicit" members rather than "mandated" members.) From alex.buckley at oracle.com Fri Nov 22 20:04:00 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 22 Nov 2019 12:04:00 -0800 Subject: Spec: ACC_MANDATED In-Reply-To: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> Message-ID: (This question was asked internally, and it wasn't clear if it was about JEP 359 (Records) specifically or ACC_MANDATED more broadly. Since the question is being driven by JEP 359 changes, and since JEP 359 is in any case the next feature which will change the JVMS, let's discuss on amber-spec-experts, NOT on compiler-dev. I have REMOVED compiler-dev from the header.) On 11/22/2019 11:22 AM, Leonid Kuskov wrote: > So specification allows RI? to mark final fields associated with > components and some methods by ACC_MANDATED flag (0x8000). The latest > JVMS specification > (https://docs.oracle.com/javase/specs/jvms/se13/html/index.html) permits > this flag only for 2 attributes: MethodParameters_attribute, > Module_attribute . The flag is not mentioned in both tables: Table > 4.5-A. "Field access and property flags", Table 4.6-A. "Method access > and property flags". ... > Does it make sense to add a definition of ACC_MANDATED to the tables? Good question. The mask 0x8000 is presently defined as ACC_MODULE in ClassFile.access_flags, but it would be legitimate to define the same mask as ACC_MANDATED in {field_info,method_info}.access_flags. This would mirror the situation for the mask 0x0020, which is defined as ACC_SUPER in ClassFile.access_flags but defined as ACC_SYNCHRONIZED in method_info.access_flags. I'm sure we have discussed ACC_MANDATED before so I'm not sure why the JEP 359 JVMS draft is silent on the matter. > And: > > Earlier the spec stated that the Enum.values() and Enum.valueOf() are > exceptions to the requirement that a class member that does not appear > in the source code must be marked using a Synthetic attribute, or have > its ACC_SYNTHETIC flag set. > Now names of methods are removed and the more loose statement "mandated > members of enums and records" is used. Does it mean that spec won't > enumerate "mandated" methods anymore? JVMS 4.7.8 should cross-ref to all JLS sections which define mandated members. JVMS 4.7.8 should not list them explicitly. (There are numerous "JLS ?..." cross-refs in JVMS ch.4, they are quite legitimate.) > And the setting of this flag will be implementation-specific? No, the presence of mandated members is JLS-defined. Search for "mandated" in JLS 13.1 to dispel any notion that mandated members are implementation-specific. > Should the JCK signature test take into account the ACC_MANDATED flag? If ACC_MANDATED is added to {field_info,method_info}.access_flags, then yes, its presence on certain members of enum and record types is required. Alex From alex.buckley at oracle.com Fri Nov 22 20:11:07 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 22 Nov 2019 12:11:07 -0800 Subject: Spec: ACC_MANDATED In-Reply-To: <3507F393-49FC-4FF0-ADAA-343E5277682E@oracle.com> References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> <3507F393-49FC-4FF0-ADAA-343E5277682E@oracle.com> Message-ID: <5e99b2a4-11b8-2c47-9769-510be662575e@oracle.com> (Removing compiler-dev. Cross-posting to *-dev and *-spec-experts list is wrong. We're discussing a question driven mainly by Records, so let's treat it as Amber spec territory.) On 11/22/2019 12:02 PM, Dan Smith wrote: >> On Nov 22, 2019, at 12:22 PM, Leonid Kuskov >> wrote: >> Does it make sense to add a definition of ACC_MANDATED to the >> tables? > > To clarify: are you saying javac is using the 0x8000 flags on fields > and methods, despite this flag being undefined in these contexts? Or > are you saying that you think we should *start* using the flag on > fields and methods, with supporting changes to the spec? > > (The first would be a bug, the second would be a minor new feature.) Leonid is asking for the second. Have I forgotten a discussion how enum/records' mandated members are represented in the class file? I see internal Slack questions every week about mandated members and reflection, but there's nothing in the JVMS draft to set expectations. (If we decided NOT to define ACC_MANDATED in {field_info,method_info}.access_flags, then the JVMS should discuss that in a note in 4.7.8, since "mandated members" are indicated there.) Alex From jonathan.gibbons at oracle.com Fri Nov 22 20:10:34 2019 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 22 Nov 2019 12:10:34 -0800 Subject: Spec: ACC_MANDATED In-Reply-To: References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> Message-ID: On 11/22/2019 12:04 PM, Alex Buckley wrote: > (This question was asked internally, and it wasn't clear if it was > about JEP 359 (Records) specifically or ACC_MANDATED more broadly. > Since the question is being driven by JEP 359 changes, and since JEP > 359 is in any case the next feature which will change the JVMS, let's > discuss on amber-spec-experts, NOT on compiler-dev. I have REMOVED > compiler-dev from the header.) > > On 11/22/2019 11:22 AM, Leonid Kuskov wrote: >> So specification allows RI? to mark final fields associated with >> components and some methods by ACC_MANDATED flag (0x8000). The latest >> JVMS specification >> (https://docs.oracle.com/javase/specs/jvms/se13/html/index.html) >> permits this flag only for 2 attributes: MethodParameters_attribute, >> Module_attribute . The flag is not mentioned in both tables: Table >> 4.5-A. "Field access and property flags", Table 4.6-A. "Method access >> and property flags". > ... >> Does it make sense to add a definition of ACC_MANDATED to the tables? > > Good question. The mask 0x8000 is presently defined as ACC_MODULE in > ClassFile.access_flags, but it would be legitimate to define the same > mask as ACC_MANDATED in {field_info,method_info}.access_flags. This > would mirror the situation for the mask 0x0020, which is defined as > ACC_SUPER in ClassFile.access_flags but defined as ACC_SYNCHRONIZED in > method_info.access_flags. I'm sure we have discussed ACC_MANDATED > before so I'm not sure why the JEP 359 JVMS draft is silent on the > matter. >> And: >> >> Earlier the spec stated that the Enum.values() and Enum.valueOf() are >> exceptions to the requirement that a class member that does not >> appear in the source code must be marked using a Synthetic attribute, >> or have its ACC_SYNTHETIC flag set. >> Now names of methods are removed and the more loose statement >> "mandated members of enums and records" is used. Does it mean that >> spec won't enumerate "mandated" methods anymore? > > JVMS 4.7.8 should cross-ref to all JLS sections which define mandated > members. JVMS 4.7.8 should not list them explicitly. (There are > numerous "JLS ?..." cross-refs in JVMS ch.4, they are quite legitimate.) > >> And the setting of this flag will be implementation-specific? > > No, the presence of mandated members is JLS-defined. Search for > "mandated" in JLS 13.1 to dispel any notion that mandated members are > implementation-specific. > >> Should the JCK signature test take into account the ACC_MANDATED flag? > > If ACC_MANDATED is added to {field_info,method_info}.access_flags, > then yes, its presence on certain members of enum and record types is > required. > > Alex Could someone also specify definitively the behavior when a user chooses to explicitly define a method, such as `equals` or `hashCode` for a record.?? In other words, just because a method may be mandated in JLS, I'm expecting that this does not imply the use of ACC_MANDATED in those situations where the user explicitly defines the method. -- jon From alex.buckley at oracle.com Fri Nov 22 20:24:21 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 22 Nov 2019 12:24:21 -0800 Subject: Spec: ACC_MANDATED In-Reply-To: References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> Message-ID: <59cc0829-3bcd-9d11-aad0-a25b0f4a6624@oracle.com> On 11/22/2019 12:10 PM, Jonathan Gibbons wrote: > Could someone also specify definitively the behavior when a user chooses > to explicitly define a method, such as `equals` or `hashCode` for a > record.?? In other words, just because a method may be mandated in JLS, > I'm expecting that this does not imply the use of ACC_MANDATED in those > situations where the user explicitly defines the method. Right, a "mandated" method is one created by the compiler because the JLS mandated (i.e. forced) the presence of the method if it wasn't explicitly declared in source code. If it was explicitly declared in source code, then it's not created by the compiler and is "just" an ordinary unflagged method (not synthetic, not mandated). This should all follow from http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html#jls-13.1 ... BTW, I see "Certain private fields and public methods of record types (8.10.3)" are not marked as mandated so I guess we're not introducing ACC_MANDATED to {field_info,method_info}.access_flags after all. JCK tests which check the mapping from source code to class file can check that an explicitly declared method is neither ACC_MANDATED nor ACC_SYNTHETIC, and that source code without an explicitly declared method gets a method which is ACC_MANDATED and not ACC_SYNTHETIC. Alex From leonid.kuskov at oracle.com Fri Nov 22 21:57:20 2019 From: leonid.kuskov at oracle.com (Leonid Kuskov) Date: Fri, 22 Nov 2019 13:57:20 -0800 Subject: Spec: ACC_MANDATED In-Reply-To: <3507F393-49FC-4FF0-ADAA-343E5277682E@oracle.com> References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> <3507F393-49FC-4FF0-ADAA-343E5277682E@oracle.com> Message-ID: On 11/22/19 12:02, Dan Smith wrote: >> On Nov 22, 2019, at 12:22 PM, Leonid Kuskov wrote: >> >> So specification allows RI to mark final fields associated with components and some methods by ACC_MANDATED flag (0x8000). The latest JVMS specification (https://docs.oracle.com/javase/specs/jvms/se13/html/index.html) permits this flag only for 2 attributes: MethodParameters_attribute, Module_attribute . The flag is not mentioned in both tables: Table 4.5-A. "Field access and property flags", Table 4.6-A. "Method access and property flags". >> Does it make sense to add a definition of ACC_MANDATED to the tables? > To clarify: are you saying javac is using the 0x8000 flags on fields and methods, despite this flag being undefined in these contexts? Or are you saying that you think we should *start* using the flag on fields and methods, with supporting changes to the spec? I'm saying javac is using the ACC_MANDATED flag on fields and methods and VM doesn't throw an exception although the spec does not permit this. Please see the example below. > > (The first would be a bug, the second would be a minor new feature.) > >> Now names of methods are removed and the more loose statement "mandated members of enums and records" is used. Does it mean that spec won't enumerate "mandated" methods anymore? And the setting of this flag will be implementation-specific? From my point of view, it might break the unambiguity of the signature tests. > I don't like putting highly specific compilation details in the JVMS description of an attribute. I don't think it's the appropriate place for those kinds of rules. I don't like this too. It is a good idea to define "mandated" members in JVMS through implicitly declared members stated in the JLS. But JVMS doesn't interact with JLS in a definition of any members at all. Could it be clarified in the VM spec? > > I *do* think we have a reasonable definition of "mandated" based on the specification of the flag, combined with what the JLS has to say about implicit declarations (see, for example, JLS 8.9.3). > > (JLS doesn't use that particular term, so depending on the answer to your first question, maybe it makes sense to rephrase this rule to talk about "implicit" members rather than "mandated" members.) I agree. BTW, JLS for Records* (chapter 13.1 Binary compatibility) states For reference, the following constructs are declared implicitly in source code, but are not marked as mandated because only formal parameters can be so marked in a|class|file (JVMS ?4.7.24): * Default constructors of classes and enum types (8.8.9 ,8.9.2 ) * *Canonical constructors of record types (8.10.4 )* * Anonymous constructors (15.9.5.1 ) * The|values|and|valueOf|methods of enum types (8.9.3 ) * Certain|public|fields of enum types (8.9.3 ) * *Certain|private|fields and|public|methods of record types (8.10.3 )* * Certain|public|methods of interfaces (9.2 ) * Container annotations (9.7.5 ) It is an extra place where implicit members don't match "mandated" members from the JVMS point of view. It would be good to be able to identify a list of implicit/mandated methods for each class/interface. For example, the record: public record Complex(double re, double im) { ? @Override ? public String toString() { ... } } is compiled to : super public final class Complex extends java/lang/Record version 58:65535 { private final mandated Field re:D; private final mandated Field im:D; public Method "":"(DD)V" ??? stack 3 locals 5 ??? 0: #{re mandated} ??? 1: #{im mandated} {} public Method toString:"()Ljava/lang/String;"{} public final mandated Method hashCode:"()I" {} public final mandated Method equals:"(Ljava/lang/Object;)Z" {} public mandated Method re:"()D" public mandated Method im:"()D" Record ?re:D, ?im:D; } Thanks, Leonid *) http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Fri Nov 22 23:30:58 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 22 Nov 2019 18:30:58 -0500 Subject: Spec: ACC_MANDATED In-Reply-To: <59cc0829-3bcd-9d11-aad0-a25b0f4a6624@oracle.com> References: <46eda485-91bb-4c5d-9d52-f15307b80b3e@oracle.com> <59cc0829-3bcd-9d11-aad0-a25b0f4a6624@oracle.com> Message-ID: <55f87bd7-b1d6-2246-708e-9c457fca20a8@oracle.com> The original intent was not to introduce ACC_MANDATED to {field,method}_info or apply it to the constructor, field, or accessors; we saw no reason to do so other than pedantic-ness. If javac is generating the flag on fields and methods, I would prefer to treat that as a bug. On 11/22/2019 3:24 PM, Alex Buckley wrote: > On 11/22/2019 12:10 PM, Jonathan Gibbons wrote: >> Could someone also specify definitively the behavior when a user >> chooses to explicitly define a method, such as `equals` or `hashCode` >> for a record.?? In other words, just because a method may be mandated >> in JLS, I'm expecting that this does not imply the use of >> ACC_MANDATED in those situations where the user explicitly defines >> the method. > > Right, a "mandated" method is one created by the compiler because the > JLS mandated (i.e. forced) the presence of the method if it wasn't > explicitly declared in source code. If it was explicitly declared in > source code, then it's not created by the compiler and is "just" an > ordinary unflagged method (not synthetic, not mandated). This should > all follow from > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html#jls-13.1 > ... BTW, I see "Certain private fields and public methods of record > types (8.10.3)" are not marked as mandated so I guess we're not > introducing ACC_MANDATED to {field_info,method_info}.access_flags > after all. > > JCK tests which check the mapping from source code to class file can > check that an explicitly declared method is neither ACC_MANDATED nor > ACC_SYNTHETIC, and that source code without an explicitly declared > method gets a method which is ACC_MANDATED and not ACC_SYNTHETIC. > > Alex From daniel.smith at oracle.com Mon Nov 25 20:42:25 2019 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 25 Nov 2019 13:42:25 -0700 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <455d46c1-8891-3312-f111-86884955f6c9@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <455d46c1-8891-3312-f111-86884955f6c9@oracle.com> Message-ID: > On Nov 6, 2019, at 11:21 AM, Alex Buckley wrote: > > On 10/31/2019 7:17 AM, Gavin Bierman wrote: >> (Alongside is a draft JVM spec for this feature: >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >> ) > > I looked at this for the CSR JDK-8233595. The `component_info` structure which is mentioned all over the place really tripped me up. Unlike fields and methods, a component isn't a first-class JVM construct, so a simple (i.e. unqualified) name is not deserved. Even the JLS always uses the qualified name, "record component" (if nothing else, to distinguish from "array component"). > > It would be wrong to replace mentions of the `component_info` structure with mentions of the `Record_attribute` structure, because `Record_attribute` isn't literally the structure which holds attributes (whereas the oft-mentioned `Code_attribute` structure really is). It would also be clunky to spell out "the `component_info` structure of the `Record_attribute` structure" in many places. > > For spec clarity, please rename `component_info` to `record_component_info`. (From a search of internal mail, I believe `component_info` was introduced around 7/24 in a discussion about annotations on record components, as an alternative to reusing the `field_info` structure in Record. Now that the term has spread throughout JVMS ch.4, it's time to name it properly.) I hadn't seen this comment, but I've now applied this change as requested (will show up next time Gavin posts an update). > As an aside, please drop "We're being intentionally vague here about just what it means for a class to have a "component"." Yep, that was intended for earlier in the design, no longer relevant. Done. > and strengthen the opener: "The Record attribute is a variable-length attribute in the attributes table of a ClassFile structure. ***A `Record` attribute indicates that this class is a _record type_ (JLS ?8.10), declared with a list of _record components_.***" [Almost certainly declared _in source code_, but maybe this class file was auto-generated, so no need to say how the record type was declared ... but it was, since here we are in its class file.] This came up in the CSR, and the conclusion was to *weaken* it?JVMS doesn't care about record types and under what conditions a class is or isn't considered a record. This sentence is purely meant to give readers some idea about why this attribute exists. So I've revised it to: "The `Record` attribute records information about the components of a record type (JLS 8.10)." From alex.buckley at oracle.com Mon Nov 25 20:54:54 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 25 Nov 2019 12:54:54 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <455d46c1-8891-3312-f111-86884955f6c9@oracle.com> Message-ID: <59e0459a-05fb-ab78-8bc7-5e4c107a8741@oracle.com> On 11/25/2019 12:42 PM, Dan Smith wrote: >> On Nov 6, 2019, at 11:21 AM, Alex Buckley >> wrote: >> For spec clarity, please rename `component_info` to >> `record_component_info`. > > I hadn't seen this comment, but I've now applied this change as > requested (will show up next time Gavin posts an update). Thanks. >> As an aside, please drop "We're being intentionally vague here >> about just what it means for a class to have a "component"." > > Yep, that was intended for earlier in the design, no longer relevant. > Done. OK. >> and strengthen the opener: "The Record attribute is a >> variable-length attribute in the attributes table of a ClassFile >> structure. ***A `Record` attribute indicates that this class is a >> _record type_ (JLS ?8.10), declared with a list of _record >> components_.***" [Almost certainly declared _in source code_, but >> maybe this class file was auto-generated, so no need to say how the >> record type was declared ... but it was, since here we are in its >> class file.] > > This came up in the CSR, and the conclusion was to *weaken* it?JVMS > doesn't care about record types and under what conditions a class is > or isn't considered a record. This sentence is purely meant to give > readers some idea about why this attribute exists. So I've revised it > to: > > "The `Record` attribute records information about the components of a > record type (JLS 8.10)." OK, though as an editorial matter, avoid a record recording something. Prefer "... of a ClassFile structure. ***A `Record` attribute denotes information about the components of a record type (JLS 8.10).***" Alex From gavin.bierman at oracle.com Mon Nov 25 23:23:48 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Mon, 25 Nov 2019 23:23:48 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: A further updated draft language spec for JEP 359 (Records) is available at: http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html along with an updated JVMS spec: http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html (Thanks to Maurizio, Alex, Tagir and others for feedback.) Main change is around the definition of canonical constructor and accessor methods. The text has changed quite a bit, but this is mainly at the surface. Hopefully this new definition is easier to understand than before and removes some corner cases (most of which were of the ?which error should arise from this program??). The idea for canonical constructors is as follows (it?s very similar for accessor methods): You are a constructor. If your signature is override-equivalent to the constructor signature derived from the record declaration in the obvious way, then you are considered a canonical constructor. (This also means that there can?t be more than one canonical constructor.) In addition, as you have been identified as a canonical constructor, you must satisfy some additional requirements, otherwise there is a compile-time error. These are: The types of the formal parameters in the formal parameter list of the canonical constructor must be identical to the declared type of the corresponding record component. A canonical constructor must not be generic (8.8.4). A canonical constructor must be declared public. A canonical constructor must not have a throws clause. The body of a canonical constructor must not contain an explicit constructor invocation statement (8.8.7.1). All the other rules for a constructor in a normal class declaration must be satisfied (8.8). We could relax some of these rules - I know Remi would like to change the third one :-) The first one is another candidate. I propose that we try these ones out in the preview, and during the preview period you can send us your experience kicking the tires with these. [One reason for this refactoring is that should we decide to relax some of these restrictions, it is a relatively simple change to the spec, which will make our lives easier for subsequent JDKs.] Many thanks, Gavin > On 21 Nov 2019, at 15:01, Gavin Bierman wrote: > > A hopefully final draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html > > This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. > > As always - any further comments/thoughts/bugs most welcome! > > Gavin > >> On 31 Oct 2019, at 14:17, Gavin Bierman > wrote: >> >> An updated draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >> >> (Alongside is a draft JVM spec for this feature: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >> >> ) >> >> As always, please email me any comments/thoughts/bugs. >> >> Thanks, >> Gavin >> >> >>> On 23 Aug 2019, at 22:25, Gavin Bierman > wrote: >>> >>> A draft language spec for records is available at: >>> >>> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >>> >>> This spec doesn?t yet discuss varargs records - to appear in the next draft. >>> >>> All comments welcomed! >>> >>> Thanks, >>> Gavin >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Mon Nov 25 23:50:08 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Mon, 25 Nov 2019 18:50:08 -0500 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: <7D05F24F-4669-422A-995B-1E143C677A7B@oracle.com> The approach is much improved. I like that it casts a wide net for things that could be confused for a canonical ctor / accessor, and then nails down conditions for its correctness, rather than trying to do both in one go ? and letting some error cases risk falling through the cracks. It also means it is easier to fine-tune the restrictions on exact type matches or accessibility or whatever. So +1. I also like that it gives accessor a standing in the language, which will be useful later when we get to deconstruction patterns, for example. > On Nov 25, 2019, at 6:23 PM, Gavin Bierman wrote: > > A further updated draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html > > along with an updated JVMS spec: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html > > (Thanks to Maurizio, Alex, Tagir and others for feedback.) > > Main change is around the definition of canonical constructor and accessor methods. The text has changed quite a bit, but this is mainly at the surface. Hopefully this new definition is easier to understand than before and removes some corner cases (most of which were of the ?which error should arise from this program??). > > The idea for canonical constructors is as follows (it?s very similar for accessor methods): You are a constructor. If your signature is override-equivalent to the constructor signature derived from the record declaration in the obvious way, then you are considered a canonical constructor. (This also means that there can?t be more than one canonical constructor.) In addition, as you have been identified as a canonical constructor, you must satisfy some additional requirements, otherwise there is a compile-time error. These are: > The types of the formal parameters in the formal parameter list of the canonical constructor must be identical to the declared type of the corresponding record component. > A canonical constructor must not be generic (8.8.4). > A canonical constructor must be declared public. > A canonical constructor must not have a throws clause. > The body of a canonical constructor must not contain an explicit constructor invocation statement (8.8.7.1). > All the other rules for a constructor in a normal class declaration must be satisfied (8.8). > We could relax some of these rules - I know Remi would like to change the third one :-) The first one is another candidate. I propose that we try these ones out in the preview, and during the preview period you can send us your experience kicking the tires with these. [One reason for this refactoring is that should we decide to relax some of these restrictions, it is a relatively simple change to the spec, which will make our lives easier for subsequent JDKs.] > > Many thanks, > Gavin > > > >> On 21 Nov 2019, at 15:01, Gavin Bierman wrote: >> >> A hopefully final draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html >> >> This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. >> >> As always - any further comments/thoughts/bugs most welcome! >> >> Gavin >> >>> On 31 Oct 2019, at 14:17, Gavin Bierman > wrote: >>> >>> An updated draft language spec for JEP 359 (Records) is available at: >>> >>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >>> >>> (Alongside is a draft JVM spec for this feature: >>> >>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >>> >>> ) >>> >>> As always, please email me any comments/thoughts/bugs. >>> >>> Thanks, >>> Gavin >>> >>> >>>> On 23 Aug 2019, at 22:25, Gavin Bierman > wrote: >>>> >>>> A draft language spec for records is available at: >>>> >>>> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >>>> >>>> This spec doesn?t yet discuss varargs records - to appear in the next draft. >>>> >>>> All comments welcomed! >>>> >>>> Thanks, >>>> Gavin >>> >> > From maurizio.cimadamore at oracle.com Mon Nov 25 23:57:48 2019 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 25 Nov 2019 23:57:48 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <7D05F24F-4669-422A-995B-1E143C677A7B@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <7D05F24F-4669-422A-995B-1E143C677A7B@oracle.com> Message-ID: <320555db-3f38-0d75-6f45-1ae3cc870711@oracle.com> +1 - I like this. We now define precisely what an accessor and a canonical constructor are - and then rule some of the explicit declarations out, with no room for ambiguities. Great job. Maurizio On 25/11/2019 23:50, Brian Goetz wrote: > The approach is much improved. I like that it casts a wide net for things that could be confused for a canonical ctor / accessor, and then nails down conditions for its correctness, rather than trying to do both in one go ? and letting some error cases risk falling through the cracks. It also means it is easier to fine-tune the restrictions on exact type matches or accessibility or whatever. So +1. > > I also like that it gives accessor a standing in the language, which will be useful later when we get to deconstruction patterns, for example. > >> On Nov 25, 2019, at 6:23 PM, Gavin Bierman wrote: >> >> A further updated draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html >> >> along with an updated JVMS spec: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html >> >> (Thanks to Maurizio, Alex, Tagir and others for feedback.) >> >> Main change is around the definition of canonical constructor and accessor methods. The text has changed quite a bit, but this is mainly at the surface. Hopefully this new definition is easier to understand than before and removes some corner cases (most of which were of the ?which error should arise from this program??). >> >> The idea for canonical constructors is as follows (it?s very similar for accessor methods): You are a constructor. If your signature is override-equivalent to the constructor signature derived from the record declaration in the obvious way, then you are considered a canonical constructor. (This also means that there can?t be more than one canonical constructor.) In addition, as you have been identified as a canonical constructor, you must satisfy some additional requirements, otherwise there is a compile-time error. These are: >> The types of the formal parameters in the formal parameter list of the canonical constructor must be identical to the declared type of the corresponding record component. >> A canonical constructor must not be generic (8.8.4). >> A canonical constructor must be declared public. >> A canonical constructor must not have a throws clause. >> The body of a canonical constructor must not contain an explicit constructor invocation statement (8.8.7.1). >> All the other rules for a constructor in a normal class declaration must be satisfied (8.8). >> We could relax some of these rules - I know Remi would like to change the third one :-) The first one is another candidate. I propose that we try these ones out in the preview, and during the preview period you can send us your experience kicking the tires with these. [One reason for this refactoring is that should we decide to relax some of these restrictions, it is a relatively simple change to the spec, which will make our lives easier for subsequent JDKs.] >> >> Many thanks, >> Gavin >> >> >> >>> On 21 Nov 2019, at 15:01, Gavin Bierman wrote: >>> >>> A hopefully final draft language spec for JEP 359 (Records) is available at: >>> >>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html >>> >>> This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. >>> >>> As always - any further comments/thoughts/bugs most welcome! >>> >>> Gavin >>> >>>> On 31 Oct 2019, at 14:17, Gavin Bierman > wrote: >>>> >>>> An updated draft language spec for JEP 359 (Records) is available at: >>>> >>>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >>>> >>>> (Alongside is a draft JVM spec for this feature: >>>> >>>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >>>> >>>> ) >>>> >>>> As always, please email me any comments/thoughts/bugs. >>>> >>>> Thanks, >>>> Gavin >>>> >>>> >>>>> On 23 Aug 2019, at 22:25, Gavin Bierman > wrote: >>>>> >>>>> A draft language spec for records is available at: >>>>> >>>>> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >>>>> >>>>> This spec doesn?t yet discuss varargs records - to appear in the next draft. >>>>> >>>>> All comments welcomed! >>>>> >>>>> Thanks, >>>>> Gavin From alex.buckley at oracle.com Tue Nov 26 02:02:59 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 25 Nov 2019 18:02:59 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: <1f71d35b-46a1-b3e6-5fee-dea1c1c43530@oracle.com> // Cutting amber-dev On 11/25/2019 3:23 PM, Gavin Bierman wrote: > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html The JVMS draft is good. It should have an informative note in 4.7.8: "It is an oversight in the design of the `class` file that there is no way to flag compiler-generated methods which are not considered implementation artifacts (JLS 13.1). This oversight means that reflective APIs may not accurately indicate the mandated status of such methods." These words may not look like much to you, but commentary about what the class file CAN'T do is pure gold to readers, and will help us recollect the situation many years from now. I accept that "more notes == more stuff to update when situations change" -- that is the risk we take for the reward of informing our readers. Alex From alex.buckley at oracle.com Tue Nov 26 02:23:59 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 25 Nov 2019 18:23:59 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: <5ec62dfc-0045-405a-2c81-73b5cbae9444@oracle.com> // Cutting amber-dev On 11/25/2019 3:23 PM, Gavin Bierman wrote: > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html The JLS draft is good. Some technical rewordings: 1. 8.10.3: "and the type as the declared type" -- missing a "same" 2. 8.10.3: Say "This field is annotated with the annotations, if any, that appear on the corresponding record component and whose annotation types are applicable in the field declaration context or in type contexts or both." (Later, for implicitly declared accessor methods, the phrase "whose annotation type is" should be "whose annotation types are". We do not constrain all the annotations to have the same annotation type, nor all the annotation types to be applicable in the same way. You could introduce an existential qualifier if you like -- "For each annotation A that appears on the corresponding ..." -- but I don't think it's necessary.) 3. 8.10.3: "A method ***declared*** in a record type R is said to be an accessor method" -- this raises questions of "explicitly or implicitly". It's too easy to think it means "explicitly" when that's not always true. Sidestep the problem by speaking more directly: "In a record type R, an _accessor method for a record component_ is a method whose name is the same as the name of the record component, and whose formal parameter list is empty." Then some refactoring because long list items are hard to follow: ----- For each record component appearing in the record component list: 1. An implicitly declared private final field ... 2. An accessor method for the record component. [THAT'S IT. DON'T RULE ON THE FORM OF EXPLICITLY DECLARED METHODS HERE. JUST MAKE SURE ALL THE METHODS EXIST:] If an accessor method for the record component is not explicitly declared, then one is implicitly declared with the following properties: - The name is the same as ... - ... It is a compile-time error if the implicitly declared accessor method is override-equivalent (8.4.2) with a non-private method of the class Object. [THIS PARAGRAPH IS TROUBLE. PLEASE MAKE AN EXPLICIT RULE IN 8.10.1 THAT SPELLS OUT IN CLEAR NORMATIVE TEXT THAT A RECORD COMPONENT MUST NOT HAVE BE CALLED CLONE, FINALIZE, ETC. RELYING ON A SUBTLE RULE IN A DIFFERENT SECTION ABOUT IMPLICITLY DECLARED STUFF IS *TOO HARD*. IT SUGGESTS THAT THE COMPILER SHOULD POSITION THE CARET FOR THE ERROR AT SOME POINT IN THE RECORD'S BODY, WHERE THE IMP.DECL. METHOD WOULD LIVE, RATHER THAN IN THE RECORD'S HEADER.] [ITEM 2 ENDS HERE. NON-LIST TEXT FOLLOWS.] If an accessor method for a record component is declared explicitly, then it must satisfy the following rules, or else a compile-time error occurs: - The return type of the accessor method ... - ... [THE FOLLOWING PARAGRAPH IS DISTINCTLY SURE -- "IS NOT ANNOTATED" -- THAT AN EXPLICIT METHOD HAS NO ANNOTATIONS LIKE THE ONES ON THE RECORD COMPONENT. WHAT IF THE DEVELOPER WRITES ANNOTATIONS EXPLICITLY? PLEASE CHANGE THE PARAGRAPH TO AN INFORMATIVE NOTE WHERE YOU CAN SAY: ANNOTATIONS THAT APPEAR ON THE CORRESPONDING RECORD COMPONENTS ARE NOT CARRIED OVER TO EXPLICITLY DECLARED ACCESSOR METHODS, IN CONTRAST TO HOW IMPLICITLY DECLARED ACCESSOR METHODS ARE ANNOTATED ACCORDING TO BLAH BLAH.] An explicitly declared accessor method is not annotated with any applicable annotation that appears on the corresponding record component. ----- 4. 8.10.4: It's odd to see in "derived constructor signature" that a ctor has a name R, since 8.8 doesn't admit to a ctor having a name. That said, 8.8.2 speaks of "two constructors with override-equivalent signatures (?8.4.2) in a class", and the definition of override equivalent implies a name is present, so I'll set my concern aside. Just a minor rewording for flow -- push derivation of formal parameter list down one level, as it's not used by anything else (OK, one place, but I'll get to that) : ----- To support proper ... corresponding to the record components. A record type R has a derived constructor signature with the name R, with no type parameters, and with a formal parameter list that is derived from the record component list of R as follows: - For each record component ... ----- 8.10.5: Construct good things, or else people will wonder: "At most one compact constructor declaration can be declared for a record type." + "In a record type R, the signature of a compact constructor declaration is the _derived constructor signature_ of R (8.10.4)." Don't say in normative text that "one which is derived from the record component list of R is added implicitly" -- "added" is too imperative -- this is an opportunity to write an informative note that compares and contrasts a compact ctor with all other ctors in Java -- "Unlike ctors in records, and indeed in classes in general, no explicit formal parameter list is given for a compact ctor. The record component list provides the X from which a Y is derived." Alex From amaembo at gmail.com Tue Nov 26 02:37:55 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 26 Nov 2019 09:37:55 +0700 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: Hello! Record construction section now sounds good to me, thanks! With best regards, Tagir Valeev. On Tue, Nov 26, 2019 at 6:24 AM Gavin Bierman wrote: > > A further updated draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html > > along with an updated JVMS spec: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html > > (Thanks to Maurizio, Alex, Tagir and others for feedback.) > > Main change is around the definition of canonical constructor and accessor methods. The text has changed quite a bit, but this is mainly at the surface. Hopefully this new definition is easier to understand than before and removes some corner cases (most of which were of the ?which error should arise from this program??). > > The idea for canonical constructors is as follows (it?s very similar for accessor methods): You are a constructor. If your signature is override-equivalent to the constructor signature derived from the record declaration in the obvious way, then you are considered a canonical constructor. (This also means that there can?t be more than one canonical constructor.) In addition, as you have been identified as a canonical constructor, you must satisfy some additional requirements, otherwise there is a compile-time error. These are: > > The types of the formal parameters in the formal parameter list of the canonical constructor must be identical to the declared type of the corresponding record component. > A canonical constructor must not be generic (8.8.4). > A canonical constructor must be declared public. > A canonical constructor must not have a throws clause. > The body of a canonical constructor must not contain an explicit constructor invocation statement (8.8.7.1). > All the other rules for a constructor in a normal class declaration must be satisfied (8.8). > > We could relax some of these rules - I know Remi would like to change the third one :-) The first one is another candidate. I propose that we try these ones out in the preview, and during the preview period you can send us your experience kicking the tires with these. [One reason for this refactoring is that should we decide to relax some of these restrictions, it is a relatively simple change to the spec, which will make our lives easier for subsequent JDKs.] > > Many thanks, > Gavin > > > > On 21 Nov 2019, at 15:01, Gavin Bierman wrote: > > A hopefully final draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html > > This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. > > As always - any further comments/thoughts/bugs most welcome! > > Gavin > > On 31 Oct 2019, at 14:17, Gavin Bierman wrote: > > An updated draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html > > (Alongside is a draft JVM spec for this feature: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html > > ) > > As always, please email me any comments/thoughts/bugs. > > Thanks, > Gavin > > > On 23 Aug 2019, at 22:25, Gavin Bierman wrote: > > A draft language spec for records is available at: > > http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html > > This spec doesn?t yet discuss varargs records - to appear in the next draft. > > All comments welcomed! > > Thanks, > Gavin > > > > From leonid.kuskov at oracle.com Tue Nov 26 04:57:32 2019 From: leonid.kuskov at oracle.com (Leonid Kuskov) Date: Mon, 25 Nov 2019 20:57:32 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> Message-ID: <2ad6a7ec-9b0a-ea7d-4255-6d42f171cc19@oracle.com> Hello, From my point of view, JVMS is not fully updated to support Records. The new spec should have? ACC_MANDATED in the tables for its consistency: ??? Table 4.5-A. "Field access and property flags" , Table 4.6-A. "Method access and property flags". otherwise, the following assertions are violated: All bits of the access_flags item not assigned in Table 4.5-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations. All bits of the access_flags item not assigned in Table 4.6-A are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations. Formally speaking, currently, fields/methods can't be marked with the? ACC_MANDATED flag. Thanks, Leonid On 11/21/19 07:01, Gavin Bierman wrote: > A hopefully final draft language spec for JEP 359 (Records) is available at: > > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html > > This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. > > As always - any further comments/thoughts/bugs most welcome! > > Gavin > >> On 31 Oct 2019, at 14:17, Gavin Bierman wrote: >> >> An updated draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >> >> (Alongside is a draft JVM spec for this feature: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >> >> ) >> >> As always, please email me any comments/thoughts/bugs. >> >> Thanks, >> Gavin >> >> >>> On 23 Aug 2019, at 22:25, Gavin Bierman > wrote: >>> >>> A draft language spec for records is available at: >>> >>> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >>> >>> This spec doesn?t yet discuss varargs records - to appear in the next draft. >>> >>> All comments welcomed! >>> >>> Thanks, >>> Gavin -------------- next part -------------- An HTML attachment was scrubbed... URL: From amaembo at gmail.com Tue Nov 26 08:12:24 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 26 Nov 2019 15:12:24 +0700 Subject: Evolution of records spec Message-ID: Hello! The current spec draft [1] tells nothing about the possibility to migrate an existing class to the record or vice versa. I believe such a migration could be safe, taking into account all the implicit declarations the records have. E.g. if I linked before to a library final class named Point, called a constructor like Point(int, int) and used equals/hashCode/toString, then converting it to the record Point(int x, int y) in the library would not break my client code. Should not we have some kind of explicit statement about record<=>class binary compatibility? With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html#jls-13.4.27 From manoj.palat at in.ibm.com Tue Nov 26 10:36:26 2019 From: manoj.palat at in.ibm.com (Manoj Palat) Date: Tue, 26 Nov 2019 10:36:26 +0000 Subject: Pattern instanceof Variable JEP clarification Message-ID: An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Tue Nov 26 10:37:22 2019 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 26 Nov 2019 11:37:22 +0100 (CET) Subject: Evolution of records spec In-Reply-To: References: Message-ID: <1897491941.799954.1574764642917.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Tagir Valeev" > ?: "amber-spec-experts" > Envoy?: Mardi 26 Novembre 2019 09:12:24 > Objet: Evolution of records spec > Hello! > > The current spec draft [1] tells nothing about the possibility to > migrate an existing class to the record or vice versa. I believe such > a migration could be safe, taking into account all the implicit > declarations the records have. E.g. if I linked before to a library > final class named Point, called a constructor like Point(int, int) and > used equals/hashCode/toString, then converting it to the record > Point(int x, int y) in the library would not break my client code. > Should not we have some kind of explicit statement about > record<=>class binary compatibility ? It's not fully binary compatible because: - a record is final (and static for internal class) - a record inherits from j.l.Record - a record requires the canonical constructor to be public - a record has a special serialization if it implements Serializable - a record is self reflective (isRecord()/getComponents()). So moving from a class to a record is mostly binary compatible if the class is not Serializable, doesn't inherits from another class and has no subclass. Moving from a record to a class is not binary compatible. > > With best regards, > Tagir Valeev. R?mi > > [1] > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html#jls-13.4.27 From gavin.bierman at oracle.com Tue Nov 26 14:17:31 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 26 Nov 2019 14:17:31 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <5ec62dfc-0045-405a-2c81-73b5cbae9444@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <5ec62dfc-0045-405a-2c81-73b5cbae9444@oracle.com> Message-ID: Thanks Alex; have made these changes to the online version. Gavin > On 26 Nov 2019, at 02:23, Alex Buckley wrote: > > // Cutting amber-dev > > On 11/25/2019 3:23 PM, Gavin Bierman wrote: >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html > > The JLS draft is good. Some technical rewordings: > > 1. 8.10.3: "and the type as the declared type" -- missing a "same" > > 2. 8.10.3: Say "This field is annotated with the annotations, if any, that appear on the corresponding record component and whose annotation types are applicable in the field declaration context or in type contexts or both." (Later, for implicitly declared accessor methods, the phrase "whose annotation type is" should be "whose annotation types are". We do not constrain all the annotations to have the same annotation type, nor all the annotation types to be applicable in the same way. You could introduce an existential qualifier if you like -- "For each annotation A that appears on the corresponding ..." -- but I don't think it's necessary.) > > 3. 8.10.3: "A method ***declared*** in a record type R is said to be an accessor method" -- this raises questions of "explicitly or implicitly". It's too easy to think it means "explicitly" when that's not always true. Sidestep the problem by speaking more directly: "In a record type R, an _accessor method for a record component_ is a method whose name is the same as the name of the record component, and whose formal parameter list is empty." Then some refactoring because long list items are hard to follow: > > ----- > For each record component appearing in the record component list: > 1. An implicitly declared private final field ... > 2. An accessor method for the record component. [THAT'S IT. DON'T RULE ON THE FORM OF EXPLICITLY DECLARED METHODS HERE. JUST MAKE SURE ALL THE METHODS EXIST:] > > If an accessor method for the record component is not explicitly declared, then one is implicitly declared with the following properties: > - The name is the same as ... > - ... > > It is a compile-time error if the implicitly declared accessor method is override-equivalent (8.4.2) with a non-private method of the class Object. [THIS PARAGRAPH IS TROUBLE. PLEASE MAKE AN EXPLICIT RULE IN 8.10.1 THAT SPELLS OUT IN CLEAR NORMATIVE TEXT THAT A RECORD COMPONENT MUST NOT HAVE BE CALLED CLONE, FINALIZE, ETC. RELYING ON A SUBTLE RULE IN A DIFFERENT SECTION ABOUT IMPLICITLY DECLARED STUFF IS *TOO HARD*. IT SUGGESTS THAT THE COMPILER SHOULD POSITION THE CARET FOR THE ERROR AT SOME POINT IN THE RECORD'S BODY, WHERE THE IMP.DECL. METHOD WOULD LIVE, RATHER THAN IN THE RECORD'S HEADER.] > > [ITEM 2 ENDS HERE. NON-LIST TEXT FOLLOWS.] > > If an accessor method for a record component is declared explicitly, then it must satisfy the following rules, or else a compile-time error occurs: > - The return type of the accessor method ... > - ... > > [THE FOLLOWING PARAGRAPH IS DISTINCTLY SURE -- "IS NOT ANNOTATED" -- THAT AN EXPLICIT METHOD HAS NO ANNOTATIONS LIKE THE ONES ON THE RECORD COMPONENT. WHAT IF THE DEVELOPER WRITES ANNOTATIONS EXPLICITLY? PLEASE CHANGE THE PARAGRAPH TO AN INFORMATIVE NOTE WHERE YOU CAN SAY: ANNOTATIONS THAT APPEAR ON THE CORRESPONDING RECORD COMPONENTS ARE NOT CARRIED OVER TO EXPLICITLY DECLARED ACCESSOR METHODS, IN CONTRAST TO HOW IMPLICITLY DECLARED ACCESSOR METHODS ARE ANNOTATED ACCORDING TO BLAH BLAH.] > An explicitly declared accessor method is not annotated with any applicable annotation that appears on the corresponding record component. > ----- > > 4. 8.10.4: It's odd to see in "derived constructor signature" that a ctor has a name R, since 8.8 doesn't admit to a ctor having a name. That said, 8.8.2 speaks of "two constructors with override-equivalent signatures (?8.4.2) in a class", and the definition of override equivalent implies a name is present, so I'll set my concern aside. Just a minor rewording for flow -- push derivation of formal parameter list down one level, as it's not used by anything else (OK, one place, but I'll get to that) : > > ----- > To support proper ... corresponding to the record components. > > A record type R has a derived constructor signature with the name R, with no type parameters, and with a formal parameter list that is derived from the record component list of R as follows: > > - For each record component ... > ----- > > 8.10.5: Construct good things, or else people will wonder: "At most one compact constructor declaration can be declared for a record type." + "In a record type R, the signature of a compact constructor declaration is the _derived constructor signature_ of R (8.10.4)." Don't say in normative text that "one which is derived from the record component list of R is added implicitly" -- "added" is too imperative -- this is an opportunity to write an informative note that compares and contrasts a compact ctor with all other ctors in Java -- "Unlike ctors in records, and indeed in classes in general, no explicit formal parameter list is given for a compact ctor. The record component list provides the X from which a Y is derived." > > Alex From brian.goetz at oracle.com Tue Nov 26 15:32:20 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 26 Nov 2019 10:32:20 -0500 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <2ad6a7ec-9b0a-ea7d-4255-6d42f171cc19@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <2ad6a7ec-9b0a-ea7d-4255-6d42f171cc19@oracle.com> Message-ID: <9C83D518-79C2-4F87-8D8A-970419454C22@oracle.com> I understand your concern here; however, the intent is _not_ to update 4.5A and 4.6A at this time. Since the compiler is setting those flags, we can treat this as a bug to be fixed. > On Nov 25, 2019, at 11:57 PM, Leonid Kuskov wrote: > > Hello, > > From my point of view, JVMS is not fully updated to support Records. > The new spec should have ACC_MANDATED in the tables for its consistency: > Table 4.5-A. "Field access and property flags" , > Table 4.6-A. "Method access and property flags". > otherwise, the following assertions are violated: > > All bits of the access_flags item not assigned in Table 4.5-A are reserved for future use. > They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations. > > All bits of the access_flags item not assigned in Table 4.6-A are reserved for future use. > They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations. > > Formally speaking, currently, fields/methods can't be marked with the ACC_MANDATED flag. > > Thanks, > Leonid > > On 11/21/19 07:01, Gavin Bierman wrote: >> A hopefully final draft language spec for JEP 359 (Records) is available at: >> >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191121/specs/records-jls.html >> >> This incorporates (I hope!) all the very helpful suggestions from everyone on these lists - many thanks. >> >> As always - any further comments/thoughts/bugs most welcome! >> >> Gavin >> >>> On 31 Oct 2019, at 14:17, Gavin Bierman wrote: >>> >>> An updated draft language spec for JEP 359 (Records) is available at: >>> >>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html >>> >>> (Alongside is a draft JVM spec for this feature: >>> >>> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jvms.html >>> >>> ) >>> >>> As always, please email me any comments/thoughts/bugs. >>> >>> Thanks, >>> Gavin >>> >>> >>>> On 23 Aug 2019, at 22:25, Gavin Bierman > wrote: >>>> >>>> A draft language spec for records is available at: >>>> >>>> http://cr.openjdk.java.net/~gbierman/8222777/8222777-20190823/specs/records-jls.html >>>> >>>> This spec doesn?t yet discuss varargs records - to appear in the next draft. >>>> >>>> All comments welcomed! >>>> >>>> Thanks, >>>> Gavin -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Tue Nov 26 15:50:54 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 26 Nov 2019 10:50:54 -0500 Subject: Evolution of records spec In-Reply-To: <1897491941.799954.1574764642917.JavaMail.zimbra@u-pem.fr> References: <1897491941.799954.1574764642917.JavaMail.zimbra@u-pem.fr> Message-ID: <4A4D7438-8338-4F47-A877-6DB4A6C82FC5@oracle.com> Remi is correct that it is not possible to make a 100% compatible migration, but only for one of the following reasons: that records extend Record, and classes CANNOT extend Record. The others are merely potholes on the way to compatibility (e.g., a class can be made final, it can have public ctors, etc.) The same is true with enums, for the same reason. That said, it would be reasonable to say _somewhere_ what a user should do if they want to maximize the compatibility of migrating between the two, as there is much that can be done. Not sure if the JLS is the place to say that, though. > It's not fully binary compatible because: > - a record is final (and static for internal class) > - a record inherits from j.l.Record > - a record requires the canonical constructor to be public > - a record has a special serialization if it implements Serializable > - a record is self reflective (isRecord()/getComponents()). > > So moving from a class to a record is mostly binary compatible if the class is not Serializable, doesn't inherits from another class and has no subclass. > Moving from a record to a class is not binary compatible. > >> >> With best regards, >> Tagir Valeev. > > R?mi > >> >> [1] >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jls.html#jls-13.4.27 -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Tue Nov 26 15:53:34 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 26 Nov 2019 07:53:34 -0800 (PST) Subject: Pattern instanceof Variable JEP clarification In-Reply-To: References: Message-ID: <4460F777-DCD3-4D6D-9F1A-5CBB067B94C9@oracle.com> > Have a few clarifications, assuming we take the following example: > > public void method foo() { > > > if (e instanceof String s) { > // s allowed > } else { > // s not allowed > } > // A: s should not be allowed here? > } In this example, s is allowed at A if and only if the ELSE block never completes normally. (In that case, in all the cases you could get to A, it is because the match succeeded, and hence s would be DA.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.smith at oracle.com Tue Nov 26 16:35:19 2019 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 26 Nov 2019 09:35:19 -0700 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <59e0459a-05fb-ab78-8bc7-5e4c107a8741@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <455d46c1-8891-3312-f111-86884955f6c9@oracle.com> <59e0459a-05fb-ab78-8bc7-5e4c107a8741@oracle.com> Message-ID: <2ED9D1CC-4A8D-4C4E-8E12-A8C9DC7D403F@oracle.com> > On Nov 25, 2019, at 1:54 PM, Alex Buckley wrote: > > OK, though as an editorial matter, avoid a record recording something. Prefer "... of a ClassFile structure. ***A `Record` attribute denotes information about the components of a record type (JLS 8.10).***" Good point. I've updated the spec source. From daniel.smith at oracle.com Tue Nov 26 16:48:16 2019 From: daniel.smith at oracle.com (Dan Smith) Date: Tue, 26 Nov 2019 09:48:16 -0700 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <1f71d35b-46a1-b3e6-5fee-dea1c1c43530@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <1f71d35b-46a1-b3e6-5fee-dea1c1c43530@oracle.com> Message-ID: <257E1A5E-7A5E-4885-B0F7-52E4B5F75E3E@oracle.com> > On Nov 25, 2019, at 7:02 PM, Alex Buckley wrote: > > // Cutting amber-dev > > On 11/25/2019 3:23 PM, Gavin Bierman wrote: >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html > > The JVMS draft is good. It should have an informative note in 4.7.8: "It is an oversight in the design of the `class` file that there is no way to flag compiler-generated methods which are not considered implementation artifacts (JLS 13.1). This oversight means that reflective APIs may not accurately indicate the mandated status of such methods." These words may not look like much to you, but commentary about what the class file CAN'T do is pure gold to readers, and will help us recollect the situation many years from now. I accept that "more notes == more stuff to update when situations change" -- that is the risk we take for the reward of informing our readers. Here's my slightly-tweaked version of this note: > It is a limitation of the `class` file that, while a method parameter or a > module may be marked `ACC_MANDATED` ([4.7.24], [4.7.25]), there is no > equivalent way to flag compiler-generated methods and fields which are not > considered implementation artifacts (JLS 13.1). > This limitation means that reflective APIs may not accurately indicate the > mandated status of such members. From alex.buckley at oracle.com Tue Nov 26 17:17:28 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 26 Nov 2019 09:17:28 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <5ec62dfc-0045-405a-2c81-73b5cbae9444@oracle.com> Message-ID: <2a7f958b-d8e8-2dc1-aef2-65c441727a68@oracle.com> Updated JLS draft looks good, thanks. On 11/26/2019 6:17 AM, Gavin Bierman wrote: > Thanks Alex; have made these changes to the online version. > > Gavin From alex.buckley at oracle.com Tue Nov 26 19:28:59 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Tue, 26 Nov 2019 11:28:59 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <257E1A5E-7A5E-4885-B0F7-52E4B5F75E3E@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <1f71d35b-46a1-b3e6-5fee-dea1c1c43530@oracle.com> <257E1A5E-7A5E-4885-B0F7-52E4B5F75E3E@oracle.com> Message-ID: <27b24ca9-2f4d-31e7-9e79-c9c12de874ef@oracle.com> On 11/26/2019 8:48 AM, Dan Smith wrote: > Here's my slightly-tweaked version of this note: > >> It is a limitation of the `class` file that, while a method parameter or a >> module may be marked `ACC_MANDATED` ([4.7.24], [4.7.25]), there is no >> equivalent way to flag compiler-generated methods and fields which are not >> considered implementation artifacts (JLS 13.1). >> This limitation means that reflective APIs may not accurately indicate the >> mandated status of such members. Thanks. (I note the change from "oversight in the design of" to "limitation of" :-) ) I don't see any changes to http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html ? Alex From gavin.bierman at oracle.com Wed Nov 27 08:59:29 2019 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Wed, 27 Nov 2019 08:59:29 +0000 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <27b24ca9-2f4d-31e7-9e79-c9c12de874ef@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <1f71d35b-46a1-b3e6-5fee-dea1c1c43530@oracle.com> <257E1A5E-7A5E-4885-B0F7-52E4B5F75E3E@oracle.com> <27b24ca9-2f4d-31e7-9e79-c9c12de874ef@oracle.com> Message-ID: <17F8D026-F12A-498F-8DAF-BD89E4A3A078@oracle.com> > On 26 Nov 2019, at 19:28, Alex Buckley wrote: > > > On 11/26/2019 8:48 AM, Dan Smith wrote: >> Here's my slightly-tweaked version of this note: >>> It is a limitation of the `class` file that, while a method parameter or a >>> module may be marked `ACC_MANDATED` ([4.7.24], [4.7.25]), there is no >>> equivalent way to flag compiler-generated methods and fields which are not >>> considered implementation artifacts (JLS 13.1). >>> This limitation means that reflective APIs may not accurately indicate the >>> mandated status of such members. > > Thanks. (I note the change from "oversight in the design of" to "limitation of" :-) ) > > I don't see any changes to http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html ? Should be there now. Thanks, Gavin From alex.buckley at oracle.com Wed Nov 27 20:01:13 2019 From: alex.buckley at oracle.com (Alex Buckley) Date: Wed, 27 Nov 2019 12:01:13 -0800 Subject: Updated Draft specs for JEP 359 (Records) In-Reply-To: <17F8D026-F12A-498F-8DAF-BD89E4A3A078@oracle.com> References: <146C0891-97B3-4DBD-AA10-CCD485357BA2@oracle.com> <3BCD6006-230D-46BA-9600-3367133703FE@oracle.com> <1f71d35b-46a1-b3e6-5fee-dea1c1c43530@oracle.com> <257E1A5E-7A5E-4885-B0F7-52E4B5F75E3E@oracle.com> <27b24ca9-2f4d-31e7-9e79-c9c12de874ef@oracle.com> <17F8D026-F12A-498F-8DAF-BD89E4A3A078@oracle.com> Message-ID: <8e6c51d5-d06c-ca68-0762-f5f52202ffd6@oracle.com> On 11/27/2019 12:59 AM, Gavin Bierman wrote: >> I don't see any changes to http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191125/specs/records-jvms.html ? > > Should be there now. This updated JVMS draft looks good, thanks. Alex From amaembo at gmail.com Thu Nov 28 03:39:30 2019 From: amaembo at gmail.com (Tagir Valeev) Date: Thu, 28 Nov 2019 10:39:30 +0700 Subject: Pattern variable and field shadowing Message-ID: Hello! Consider the following code: public class A { private String str; public void f(Object obj) { if (obj instanceof String str) { System.out.println(str.toLowerCase()); // str refers to pattern binding } else { System.out.println(str.toLowerCase()); // str refers to the field } } } I thought that such a code should be rejected by the compiler, as it's confusing and could be a source of very subtle bugs. However, I haven't found any explicit statement regarding this in the latest spec draft [1]. Could you please clarify whether such code is acceptable and point me to the relevant part of the spec draft. Thank you! With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html From brian.goetz at oracle.com Thu Nov 28 13:41:57 2019 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 28 Nov 2019 08:41:57 -0500 Subject: Pattern variable and field shadowing In-Reply-To: References: Message-ID: We struggled with this one - we call it the ?Swiss cheese? problem. The current rules are cheese-friendly. We considered trying to rule it out but we were concerned that the cure would be more complex than was worth it. Sent from my iPad > On Nov 27, 2019, at 10:39 PM, Tagir Valeev wrote: > > Hello! > > Consider the following code: > > public class A { > private String str; > > public void f(Object obj) { > if (obj instanceof String str) { > System.out.println(str.toLowerCase()); // str refers to > pattern binding > } else { > System.out.println(str.toLowerCase()); // str refers to the field > } > } > } > > I thought that such a code should be rejected by the compiler, as it's > confusing and could be a source of very subtle bugs. However, I > haven't found any explicit statement regarding this in the latest spec > draft [1]. Could you please clarify whether such code is acceptable > and point me to the relevant part of the spec draft. Thank you! > > With best regards, > Tagir Valeev. > > [1] http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html