From forax at univ-mlv.fr Thu Feb 6 20:38:29 2020 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 6 Feb 2020 21:38:29 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> Message-ID: <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> [moved to amber-spec] ----- Mail original ----- > De: "jan lahoda" > ?: "amber-dev" > Envoy?: Jeudi 6 F?vrier 2020 21:18:52 > Objet: Pattern Matching for instanceof (Preview 2) > Hi, > > Thanks to Gavin, Brian and Alex, there is a new draft JEP for Pattern > Matching for instanceof (Preview 2): > https://bugs.openjdk.java.net/browse/JDK-8235186 > > Any feedback on the JEP is more than welcome! > > Thanks, > Jan so the difference with the previous preview is that deconstruction is added. I see two questions: - the grammar allows to mix var and non-var for a given reference type, i think that should only permitted if the non var is a deconstruction itself ? - must the identifier of a pattern argument be the same name as the corresponding record component ? To be coherent with the fact that constructors requires the same names. cheers, R?mi From brian.goetz at oracle.com Thu Feb 6 22:04:05 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 6 Feb 2020 17:04:05 -0500 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> Message-ID: <586067c9-33c2-5ace-bc8f-ab22cb913f1f@oracle.com> > I see two questions: > - the grammar allows to mix var and non-var for a given reference type, i think that should only permitted if the non var is a deconstruction itself ? More generally, any pattern can appear nested inside a deconstruction pattern -- another deconstruction pattern, a var (any) pattern, a type pattern, a constant pattern ... we may not have them all right now, but any pattern will do. > - must the identifier of a pattern argument be the same name as the corresponding record component ? > To be coherent with the fact that constructors requires the same names. Nope!? This is the use site; the client can name their locals however they like.? Invocation of deconstructors, like constructors, is positional. From forax at univ-mlv.fr Thu Feb 6 22:21:36 2020 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 6 Feb 2020 23:21:36 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <586067c9-33c2-5ace-bc8f-ab22cb913f1f@oracle.com> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <586067c9-33c2-5ace-bc8f-ab22cb913f1f@oracle.com> Message-ID: <170741032.589508.1581027696314.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Brian Goetz" > ?: "Remi Forax" , "jan lahoda" > Cc: "amber-spec-experts" > Envoy?: Jeudi 6 F?vrier 2020 23:04:05 > Objet: Re: Pattern Matching for instanceof (Preview 2) >> I see two questions: >> - the grammar allows to mix var and non-var for a given reference type, i think >> that should only permitted if the non var is a deconstruction itself ? > > More generally, any pattern can appear nested inside a deconstruction > pattern -- another deconstruction pattern, a var (any) pattern, a type > pattern, a constant pattern ... we may not have them all right now, but > any pattern will do. var is not really any, it's an inferred type pattern. '_' is any, no ? > >> - must the identifier of a pattern argument be the same name as the >> corresponding record component ? >> To be coherent with the fact that constructors requires the same names. > > Nope!? This is the use site; the client can name their locals however > they like.? Invocation of deconstructors, like constructors, is positional. Ok, make sense. R?mi From brian.goetz at oracle.com Thu Feb 6 23:00:40 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 6 Feb 2020 18:00:40 -0500 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <170741032.589508.1581027696314.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <586067c9-33c2-5ace-bc8f-ab22cb913f1f@oracle.com> <170741032.589508.1581027696314.JavaMail.zimbra@u-pem.fr> Message-ID: <407eaf5e-1095-2afa-ce2f-e30ccfe7533a@oracle.com> > var is not really any, it's an inferred type pattern. > '_' is any, no ? Conveniently, an inferred type pattern _is_ an any pattern.? (See the explanation in the recent discussion on nullity, where this fell out nicely.)?? So semantically a var pattern is an any pattern. Whether or not we want an explicit any pattern is a separate question. From forax at univ-mlv.fr Thu Feb 6 23:08:24 2020 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 7 Feb 2020 00:08:24 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <407eaf5e-1095-2afa-ce2f-e30ccfe7533a@oracle.com> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <586067c9-33c2-5ace-bc8f-ab22cb913f1f@oracle.com> <170741032.589508.1581027696314.JavaMail.zimbra@u-pem.fr> <407eaf5e-1095-2afa-ce2f-e30ccfe7533a@oracle.com> Message-ID: <702546939.595255.1581030504502.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Brian Goetz" > ?: "Remi Forax" > Cc: "jan lahoda" , "amber-spec-experts" > Envoy?: Vendredi 7 F?vrier 2020 00:00:40 > Objet: Re: Pattern Matching for instanceof (Preview 2) >> var is not really any, it's an inferred type pattern. >> '_' is any, no ? > > Conveniently, an inferred type pattern _is_ an any pattern.? (See the > explanation in the recent discussion on nullity, where this fell out > nicely.)?? So semantically a var pattern is an any pattern. not if there are multiple de-constructors with the same arity, right ? > Whether or not we want an explicit any pattern is a separate question. R?mi From brian.goetz at oracle.com Thu Feb 6 23:26:54 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 6 Feb 2020 18:26:54 -0500 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <702546939.595255.1581030504502.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <586067c9-33c2-5ace-bc8f-ab22cb913f1f@oracle.com> <170741032.589508.1581027696314.JavaMail.zimbra@u-pem.fr> <407eaf5e-1095-2afa-ce2f-e30ccfe7533a@oracle.com> <702546939.595255.1581030504502.JavaMail.zimbra@u-pem.fr> Message-ID: >> Conveniently, an inferred type pattern _is_ an any pattern.? (See the >> explanation in the recent discussion on nullity, where this fell out >> nicely.)?? So semantically a var pattern is an any pattern. > not if there are multiple de-constructors with the same arity, right ? It still is an _any_ pattern.? If there are multiple same-arity dtors, we have an overload selection problem.? And we'd have the same overload selection whether the client said `case Foo(var x)` and `case Foo(__ANY_PATTERN__)`, because in neither case is there enough type information at the use site to perform the overload selection. From amaembo at gmail.com Tue Feb 11 03:23:22 2020 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 11 Feb 2020 10:23:22 +0700 Subject: [359] Record - Compact Constructor should not have throws clause In-Reply-To: References: Message-ID: Hello! ??, 11 ????. 2020 ?., 10:18 Manoj Palat : > Hi, > > consider > record R(){ > public R throws Exception {} > } > > From JLS 14 Sec 8.10.4, > A canonical constructor must not have a throws clause. > > Sec 8.10.5 says > A compact constructor is a canonical constructor. > > By the above two, it can be inferred that a compact constructor must not have a throws clause. However, there is no explicit mention of this restriction in Sec 8.10.5 [1] > > I think it would good to add this explicitly in the next version of spec (assuming the above is true). > > This unambiguously follows from the compact constructor declaration production: *CompactConstructorDeclaration*:{ *Annotation* } { *ConstructorModifier* } *SimpleTypeName* *ConstructorBody* No throws at all here. To me, this is enough and no changes are necessary. With best regards, Tagir Valeev. [1] http://cr.openjdk.java.net/~gbierman/jep359/jep359-20200115/specs/records-jls.html#jls-8.10.5 > Regards, > Manoj. > > Side Note: > To compare, javac throws errors but not this particular error (may be due to error recovery) > javac14 --enable-preview --release 14 X.java > X.java:2: error: expected > public R throws Exception {} > ^ > X.java:2: error: field declaration must be static > public R throws Exception {} > ^ > (consider replacing field with record component) > X.java:2: error: invalid method declaration; return type required > public R throws Exception {} > > > > From vicente.romero at oracle.com Tue Feb 11 04:17:28 2020 From: vicente.romero at oracle.com (Vicente Romero) Date: Mon, 10 Feb 2020 23:17:28 -0500 Subject: [359] Record - Compact Constructor should not have throws clause In-Reply-To: References: Message-ID: <686a6953-11d9-9654-8892-12f7984b32f3@oracle.com> On the spec side I agree with Tagir. On the compiler error messages I will file an issue to check if we can generate a better error message, Thanks, Vicente On 2/10/20 10:23 PM, Tagir Valeev wrote: > Hello! > > ??, 11 ????. 2020 ?., 10:18 Manoj Palat >: > > Hi, > > consider > record R(){ > public R throws Exception {} > } > > From JLS 14 Sec 8.10.4, > A canonical constructor must not have a throws clause. > > Sec 8.10.5 says > A compact constructor is a canonical constructor. > > By the above two, it can be inferred that a compact constructor must not have a throws clause. However, there is no explicit mention of this restriction in Sec 8.10.5 [1] > > I think it would good to add this explicitly in the next version of spec (assuming the above is true). > > > This unambiguously follows from the compact constructor declaration > production: > > /CompactConstructorDeclaration/: > { /Annotation/?} { /ConstructorModifier/?} /SimpleTypeName/ > /ConstructorBody/ > > No throws at all here. To me, this is enough and no changes are necessary. > > With best regards, > Tagir Valeev. > > [1]http://cr.openjdk.java.net/~gbierman/jep359/jep359-20200115/specs/records-jls.html#jls-8.10.5 > Regards, > Manoj. > > Side Note: > To compare, javac throws errors but not this particular error (may be due to error recovery) > javac14 --enable-preview --release 14 X.java > X.java:2: error: expected > public R throws Exception {} > ^ > X.java:2: error: field declaration must be static > public R throws Exception {} > ^ > (consider replacing field with record component) > X.java:2: error: invalid method declaration; return type required > public R throws Exception {} > > From vicente.romero at oracle.com Fri Feb 14 13:38:40 2020 From: vicente.romero at oracle.com (Vicente Romero) Date: Fri, 14 Feb 2020 08:38:40 -0500 Subject: [359] Record - Compact Constructor should not have throws clause In-Reply-To: References: <686a6953-11d9-9654-8892-12f7984b32f3@oracle.com> Message-ID: <3ed700a6-28e5-6602-29b1-98fa98a32b45@oracle.com> right, the issue has been fixed, thanks again for the report, Vicente On 2/12/20 11:18 PM, Manoj Palat wrote: > Sure. I see JDK-8238838? filed. > Thanks, > Manoj > > ----- Original message ----- > From: Vicente Romero > To: Tagir Valeev , Manoj Palat > > Cc: amber-spec-experts > Subject: [EXTERNAL] Re: [359] Record - Compact Constructor should > not have throws clause > Date: Tue, Feb 11, 2020 9:47 AM > > On the spec side I agree with Tagir. On the compiler error > messages I will file an issue to check if we can generate a better > error message, > > Thanks, > Vicente > On 2/10/20 10:23 PM, Tagir Valeev wrote: >> Hello! >> ??, 11 ????. 2020 ?., 10:18 Manoj Palat > >: >> >> Hi, >> >> consider >> record R(){ >> ?? ? ? ?public R throws Exception {} >> } >> >> From JLS 14 Sec 8.10.4, >> A canonical constructor must not have a throws clause. >> >> Sec 8.10.5 says >> A compact constructor is a canonical constructor. >> >> By the above two, it can be inferred that a compact >> constructor must not have a throws clause. However, there is >> no explicit mention of this restriction in Sec 8.10.5 [1] >> >> I think it would good to add this explicitly in the next >> version of spec (assuming the above is true). >> >> This unambiguously follows from the compact constructor >> declaration production: >> >> /CompactConstructorDeclaration/: >> { /Annotation/?} { /ConstructorModifier/?} /SimpleTypeName/ >> /ConstructorBody/ >> >> No throws at all here. To me, this is enough and no changes are >> necessary. >> With best regards, >> Tagir Valeev. >> >> [1] >> http://cr.openjdk.java.net/~gbierman/jep359/jep359-20200115/specs/records-jls.html#jls-8.10.5 >> Regards, >> Manoj. >> >> Side Note: >> To compare, javac throws errors but not this particular error >> (may be due to error recovery) >> javac14 --enable-preview --release 14 X.java >> X.java:2: error: expected >> ?? ? ? ?public R throws Exception {} >> ?? ? ? ? ? ? ? ?^ >> X.java:2: error: field declaration must be static >> ?? ? ? ?public R throws Exception {} >> ?? ? ? ? ? ? ? ? ^ >> ??(consider replacing field with record component) >> X.java:2: error: invalid method declaration; return type required >> ?? ? ? ?public R throws Exception {} >> > From gavin.bierman at oracle.com Tue Feb 18 14:32:12 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 18 Feb 2020 14:32:12 +0000 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> Message-ID: <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> [Just circling back to this, as I added a note about the grammar to the JEP page?] > On 6 Feb 2020, at 20:38, Remi Forax wrote: > > [moved to amber-spec] > > ----- Mail original ----- >> De: "jan lahoda" >> ?: "amber-dev" >> Envoy?: Jeudi 6 F?vrier 2020 21:18:52 >> Objet: Pattern Matching for instanceof (Preview 2) > >> Hi, >> >> Thanks to Gavin, Brian and Alex, there is a new draft JEP for Pattern >> Matching for instanceof (Preview 2): >> https://bugs.openjdk.java.net/browse/JDK-8235186 >> >> Any feedback on the JEP is more than welcome! >> >> Thanks, >> Jan > > so the difference with the previous preview is that deconstruction is added. That is correct. > > I see two questions: > - the grammar allows to mix var and non-var for a given reference type, i think that should only permitted if the non var is a deconstruction itself ? I don?t know what you mean here. There are two patterns, a type test pattern and a deconstruction pattern. In v2 we propose to support deconstruction patterns over record types *only*. A deconstruction pattern looks like this: Point(var a, var b), i.e. all the components are either (recursively) deconstruction patterns, or `var` , i.e. with no type needed. I added a note to the JEP page pointing out that this is a starting point, and eventually we will support other patterns in the argument position, specifically ; hopefully in this release. > - must the identifier of a pattern argument be the same name as the corresponding record component ? > To be coherent with the fact that constructors requires the same names. Absolutely not! Note this does mean that you can write confusing code: record Point(int x, int y) { } if (o instanceof Point(var y, var x)) { ? // y refers to x component, y refers to x component } (I?ll get my coat?) Thanks, Gavin From forax at univ-mlv.fr Tue Feb 18 15:04:47 2020 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Tue, 18 Feb 2020 16:04:47 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> Message-ID: <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> Hi Gavin, ----- Mail original ----- > De: "Gavin Bierman" > ?: "Remi Forax" > Cc: "jan lahoda" , "amber-spec-experts" > Envoy?: Mardi 18 F?vrier 2020 15:32:12 > Objet: Re: Pattern Matching for instanceof (Preview 2) > [Just circling back to this, as I added a note about the grammar to the JEP > page?] > >> On 6 Feb 2020, at 20:38, Remi Forax wrote: >> >> [moved to amber-spec] >> >> ----- Mail original ----- >>> De: "jan lahoda" >>> ?: "amber-dev" >>> Envoy?: Jeudi 6 F?vrier 2020 21:18:52 >>> Objet: Pattern Matching for instanceof (Preview 2) >> >>> Hi, >>> >>> Thanks to Gavin, Brian and Alex, there is a new draft JEP for Pattern >>> Matching for instanceof (Preview 2): >>> https://bugs.openjdk.java.net/browse/JDK-8235186 >>> >>> Any feedback on the JEP is more than welcome! >>> >>> Thanks, >>> Jan >> >> so the difference with the previous preview is that deconstruction is added. > > That is correct. > >> >> I see two questions: >> - the grammar allows to mix var and non-var for a given reference type, i think >> that should only permitted if the non var is a deconstruction itself ? > > I don?t know what you mean here. There are two patterns, a type test pattern and > a deconstruction pattern. In v2 we propose to support deconstruction patterns > over record types *only*. A deconstruction pattern looks like this: Point(var > a, var b), i.e. all the components are either (recursively) deconstruction > patterns, or `var` , i.e. with no type needed. I added a note to > the JEP page pointing out that this is a starting point, and eventually we will > support other patterns in the argument position, specifically > ; hopefully in this release. Currently we don't support mixing var and non var in lambda parameters. So my question is: does this pattern Point(var x, int y) that mix a 'var' and an explicit type allowed or not ? > > >> - must the identifier of a pattern argument be the same name as the >> corresponding record component ? >> To be coherent with the fact that constructors requires the same names. > > Absolutely not! Note this does mean that you can write confusing code: > > record Point(int x, int y) { } > > if (o instanceof Point(var y, var x)) { > ? // y refers to x component, y refers to x component > } > > (I?ll get my coat?) yes, that's why i ask, it leads to very confusing code, some languages don't allow this kind of code, by example destructuring in JavaScript as a special syntax if you want to use different names. > > Thanks, > Gavin regards, R?mi From brian.goetz at oracle.com Tue Feb 18 15:14:57 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 18 Feb 2020 10:14:57 -0500 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> Message-ID: <7e3a649d-62a3-2a31-d755-9282272e9c4c@oracle.com> >> I don?t know what you mean here. There are two patterns, a type test pattern and >> a deconstruction pattern. In v2 we propose to support deconstruction patterns >> over record types *only*. A deconstruction pattern looks like this: Point(var >> a, var b), i.e. all the components are either (recursively) deconstruction >> patterns, or `var` , i.e. with no type needed. I added a note to >> the JEP page pointing out that this is a starting point, and eventually we will >> support other patterns in the argument position, specifically >> ; hopefully in this release. > Currently we don't support mixing var and non var in lambda parameters. > So my question is: does this pattern Point(var x, int y) that mix a 'var' and an explicit type allowed or not ? Unequivocal "yes".?? There is a universe of patterns.? Some might be disallowed in certain contexts (e.g., `instanceof var x` seems kind of silly), but once we decide on the set of patterns allowable in which contexts, any pattern can be nested inside a deconstruction pattern. The `var x` pattern can equally be thought of as inference for a total type pattern, or an "any" pattern; they are semantically equivalent. If you're asking "but why can I not mix them in a lambda", the answer is: because we don't support partial inference in lambdas at this time.? We could, and we might someday.? (If you're suggesting that the consistency between the two superficially-related forms is the most important consideration here, I would disagree.) > >> Absolutely not! Note this does mean that you can write confusing code: >> >> record Point(int x, int y) { } >> >> if (o instanceof Point(var y, var x)) { >> ? // y refers to x component, y refers to x component >> } >> >> (I?ll get my coat?) > yes, that's why i ask, it leads to very confusing code, some languages don't allow this kind of code, > by example destructuring in JavaScript as a special syntax if you want to use different names. > Preventing this kind of confusing code (which is just a special case of "picking stupid names") is much more of a job for IDEs than language specifications. From gavin.bierman at oracle.com Tue Feb 18 15:16:40 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 18 Feb 2020 15:16:40 +0000 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> Message-ID: > On 18 Feb 2020, at 15:04, forax at univ-mlv.fr wrote: > > Hi Gavin, > > ----- Mail original ----- >> De: "Gavin Bierman" >> ?: "Remi Forax" >> Cc: "jan lahoda" , "amber-spec-experts" >> Envoy?: Mardi 18 F?vrier 2020 15:32:12 >> Objet: Re: Pattern Matching for instanceof (Preview 2) > >> [Just circling back to this, as I added a note about the grammar to the JEP >> page?] >> >>> On 6 Feb 2020, at 20:38, Remi Forax wrote: >>> >>> [moved to amber-spec] >>> >>> ----- Mail original ----- >>>> De: "jan lahoda" >>>> ?: "amber-dev" >>>> Envoy?: Jeudi 6 F?vrier 2020 21:18:52 >>>> Objet: Pattern Matching for instanceof (Preview 2) >>> >>>> Hi, >>>> >>>> Thanks to Gavin, Brian and Alex, there is a new draft JEP for Pattern >>>> Matching for instanceof (Preview 2): >>>> https://bugs.openjdk.java.net/browse/JDK-8235186 >>>> >>>> Any feedback on the JEP is more than welcome! >>>> >>>> Thanks, >>>> Jan >>> >>> so the difference with the previous preview is that deconstruction is added. >> >> That is correct. >> >>> >>> I see two questions: >>> - the grammar allows to mix var and non-var for a given reference type, i think >>> that should only permitted if the non var is a deconstruction itself ? >> >> I don?t know what you mean here. There are two patterns, a type test pattern and >> a deconstruction pattern. In v2 we propose to support deconstruction patterns >> over record types *only*. A deconstruction pattern looks like this: Point(var >> a, var b), i.e. all the components are either (recursively) deconstruction >> patterns, or `var` , i.e. with no type needed. I added a note to >> the JEP page pointing out that this is a starting point, and eventually we will >> support other patterns in the argument position, specifically >> ; hopefully in this release. > > Currently we don't support mixing var and non var in lambda parameters. > So my question is: does this pattern Point(var x, int y) that mix a 'var' and an explicit type allowed or not ? Aha. So, we?re not at that stage yet - this isn?t allowed by the spec as it stands. This - and many other issues - is why I?m starting small? Do you have a preference? Gavin From gavin.bierman at oracle.com Tue Feb 18 15:19:48 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 18 Feb 2020 15:19:48 +0000 Subject: [records] Summary so far Message-ID: Dear Experts: In [1] Brian asked for comments on some remaining design decisions concerning records (and asked for any new ones that you'd like to raise). First, thank you for your feedback so far! I have been through the threads, and tried to summarize the question and the current status below. Of course, these decisions are not set in stone, but the point of this email is to warn you that they are hardening :-) So, if you disagree, or would like further discussion, *now* is the time to speak up! Q1. Should the distinguished supertype of records java.lang.Record be renamed? [Since the original post, it seems that inline types will be able to inherit from abstract classes.] Is the name "Record" a good one? It has good clash potential :-) possible alternatives are RecordClass, or AbstractRecord? A: No consensus so far. Q2. Accessibilty of mandated members. Currently the mandated members are public regardless of the accessibility of the record type. What should be the default accessibility for record members? A: Currently the most popular proposal is that mandated members get accessibility of the record type. Other members get package level accessibility as per a regular class. (Note: it should be legal for explicit declarations of mandated members to specify something _more_ accessible (same rules as overriding.) ) Q3. Nesting. A: We are working on a new spec that removes a lot of restriction regarding nested classes/records. Q4. Abstract records. Should we allow the declaration of abstract classes, possibly supporting some form of record subtyping? A: No support for this. Q5. Deconstruction patterns. A: We will be proposing deconstruction patterns in the patterns v2 preview. Q6. @deprecated Should we allow record components to be marked as @deprecated? A: We don't want to add any additional support for @deprecated beyond the fact that it is an annotation and it can be inspected via reflection. Q7. .equals and .toString are slow. Remi [2] points out that the current implementations of .equals and .toString are slow. A: We will look into this. Q8. Translation strategy. John [3] suggested changing the compilation strategy of records so we can future-proof the evolution of members from the record supertype. A: No change. Q9. Hashing. John [4] proposed weakening of the .hashCode spec. A: Agreed. John has written candidate text [5]. Q10. Special annotation for explicit declaration of accessors. Tagir [6] proposes a new `@RecordAccessor` annotation to mark explicit accessors, much as `@Override` is used to mark method overrides. A: Rather than introduce a new accessor, we will consider extending the meaning of the `@Override` annotation to include this case. Q11. Changing the spec of .toString method We should weaken the spec of the .toString method so it explicitly states that the form of the string produced is subject to change and can not be relied upon. A: Agreed. Q12. Transactional methods Canonical constructors are an instance of a general pattern where a set of variables are in scope for a given block, and assigned values at the end. This could be a useful abstraction to be given first-class representation. A: No change. More research needed. Q13. Factory methods instead of constructors. Should "new R(v1, ..., vn)" be compiled to a factory method, to allow future-proofing with inline types? A: No change for now. Thanks for your comments and discussions so far. If you disagree with anything written here, please reply! Thanks, Gavin [1] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001913.html [2] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001943.html [3] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001937.html [4] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001935.html [5] http://cr.openjdk.java.net/~jrose/draft/record-contract [6] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001931.html From gavin.bierman at oracle.com Tue Feb 18 15:47:24 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 18 Feb 2020 15:47:24 +0000 Subject: [sealed] Changes to type system Message-ID: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> Dear Experts: One aspect of sealed types that we have not discussed before, is that it suggests a change in the type system. This change regards conversions used in casting contexts. For example, in Java right now: interface I {} class C {} // does not implement I void test (C c) { if (c instanceof I) System.out.println("It's an I"); } This compiles even though it is *currently* not possible for a C object to implement the interface I. Of course, it might be, for example: class B extends C implements I {} test(new B()); // Prints "It's an I" So, the conversion rules capture "open extensibility"; i.e. the Java type system does not assume a closed world, classes and interfaces could be extended, and casting conversions compile to runtime tests, so we can safely be flexible. However, at the other end of the spectrum the conversion rules do address the case where a class can *not* be extended, i.e. when it is a *final* class. final class C {} void test (C c) { if (c instanceof I) System.out.println("It's an I"); } The method test fails to compile, as the compiler knows that there can be no subclass of C, so as C does not implement I then it is never possible for a C value to implement I. This is a compile-time error. But what about if C is not final, but *sealed*? Given that its direct subclasses are explicitly enumerated, and - by the definition of being sealed - in the same module, we would surely expect the compiler to look to see if it can spot a similar compile-time error. Consider the following code: interface I {} sealed class C permits D {} final class D extends C {} void test (C c) { if (c instanceof I) System.out.println("It's an I"); } Class C does not implement I, and is not final - so by the old rules we might conclude that there is a conversion - but it is sealed. There is one permitted direct subclass of C: D. By definition of sealed types, D must be either final, sealed or non-sealed. In this example, all the direct subclasses of C are final and do not implement I, so in fact we can safely reject this program, as there cannot be a subtype of C that implements I. In contrast, consider a similar program where one of the direct subclasses of the sealed class is non-sealed: interface I {} sealed class C permits D, E {} non-sealed class D extends C {} final class E extends C {} void test (C c) { if (c instanceof I) System.out.println("It's an I"); } This is type correct as it is possible for a subtype of the non-sealed type D to implement I. The trick is to extend the notion of allowed narrowing reference conversion (JLS 5.1.6.1) to follow the sealed type declarations. I'll spare you the gory details in this email - they will appear in the JLS draft appearing soon (!) - but I wanted to check that this extension to the type system seems reasonable. Obviously it will be putting more strain on the type checker. Is everyone happy with this extension? Thanks, Gavin PS: Some further examples for your amusement: Example 1: ---------- non-sealed interface I {} non-sealed interface J {} I i; if (i instanceof J) {} // Yes! Example 2: ---------- sealed interface I permits C {} final class C implements I {} non-sealed interface J {} I i; if (i instanceof J) {} // Error, only instance of I is C // Which doesn?t implement J Example 3: ---------- non-sealed interface I {} sealed interface J permits C {} final class C implements J {} I i; if (i instanceof J) {} // Error, only instance of J is C // which doesn?t implement I Example 4: ---------- sealed interface I permits A {} sealed interface J permits B {} final class A implements I {} final class B implements J {} I i; if (i instanceof J) {} // Error, similar to above Example 5: ---------- non-sealed class C {} non-sealed interface I {} C c; if (c instanceof I) {} // Yes! Example 6: ---------- non-sealed class C {} sealed interface I permits A {} final class A implements I {} C c; if (c instanceof I) {} // Error Example 7: ---------- final class C {} non-sealed interface I {} C c; if (c instanceof I) {} // Error Example 8: ---------- final class C {} sealed interface I permits D {} final class D implements I {} C c; if (c instanceof I) {} // Error Example 9: ---------- sealed class C permits D {} final class D extends C {} non-sealed interface I {} C c; if (c instanceof I) {} // Error Example 10: ----------- sealed class C permits D {} final class D {} sealed interface I permits E {} final class E {} C c; if (c instanceof I) {} // Error Example 11: ----------- non-sealed interface I {} non-sealed class C {} I i; if (i instanceof C) {} // Yes! Example 12: ----------- non-sealed interface I {} final class C {} I i; if (i instanceof C) {} // Error Example 13: ----------- non-sealed interface I {} sealed class C permits D {} final class D {} I i; if (i instanceof C) {} // Error Example 14: ----------- sealed interface I permits D {} final class D {} non-sealed class C {} I i; if (i instanceof C) {} // Error Example 15: ----------- sealed interface I permits D {} final class D implements I {} final class C {} I i; if (i instanceof C) {} // Error Example 16: ----------- sealed interface I permits D {} final class D implements I {} sealed class C permits E {} final class E extends C {} I i; if (i instanceof C) {} // Error From amaembo at gmail.com Tue Feb 18 16:01:22 2020 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 18 Feb 2020 23:01:22 +0700 Subject: [sealed] Changes to type system In-Reply-To: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> References: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> Message-ID: I would be happy to see this implemented: the more errors are reported by compiler the better and less buggy programs we have. However, I worry about compiler performance. The permits hierarchy can be quite deep and wide and compiler will need to traverse it completely in these cases. With best regards, Tagir Valeev On Tue, Feb 18, 2020 at 10:47 PM Gavin Bierman wrote: > > Dear Experts: > > One aspect of sealed types that we have not discussed before, is that it > suggests a change in the type system. > > This change regards conversions used in casting contexts. For example, in Java > right now: > > interface I {} > class C {} // does not implement I > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > This compiles even though it is *currently* not possible for a C object to > implement the interface I. Of course, it might be, for example: > > class B extends C implements I {} > > test(new B()); > // Prints "It's an I" > > So, the conversion rules capture "open extensibility"; i.e. the Java type system > does not assume a closed world, classes and interfaces could be extended, and > casting conversions compile to runtime tests, so we can safely be flexible. > > However, at the other end of the spectrum the conversion rules do address > the case where a class can *not* be extended, i.e. when it is a *final* class. > > final class C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > The method test fails to compile, as the compiler knows that there can be no > subclass of C, so as C does not implement I then it is never possible for a C > value to implement I. This is a compile-time error. > > But what about if C is not final, but *sealed*? Given that its direct subclasses > are explicitly enumerated, and - by the definition of being sealed - in the same > module, we would surely expect the compiler to look to see if it can spot a > similar compile-time error. Consider the following code: > > interface I {} > sealed class C permits D {} > final class D extends C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > Class C does not implement I, and is not final - so by the old rules we might > conclude that there is a conversion - but it is sealed. There is one permitted > direct subclass of C: D. By definition of sealed types, D must be either final, > sealed or non-sealed. In this example, all the direct subclasses of C are final > and do not implement I, so in fact we can safely reject this program, as there > cannot be a subtype of C that implements I. > > In contrast, consider a similar program where one of the direct subclasses of > the sealed class is non-sealed: > > interface I {} > sealed class C permits D, E {} > non-sealed class D extends C {} > final class E extends C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > This is type correct as it is possible for a subtype of the non-sealed type D to > implement I. > > The trick is to extend the notion of allowed narrowing reference conversion (JLS > 5.1.6.1) to follow the sealed type declarations. I'll spare you the gory details > in this email - they will appear in the JLS draft appearing soon (!) - but I > wanted to check that this extension to the type system seems reasonable. > Obviously it will be putting more strain on the type checker. Is everyone happy > with this extension? > > Thanks, > Gavin > > > PS: Some further examples for your amusement: > > Example 1: > ---------- > > non-sealed interface I {} > non-sealed interface J {} > > I i; > if (i instanceof J) {} // Yes! > > Example 2: > ---------- > > sealed interface I permits C {} > final class C implements I {} > non-sealed interface J {} > > I i; > if (i instanceof J) {} // Error, only instance of I is C > // Which doesn?t implement J > > Example 3: > ---------- > > non-sealed interface I {} > sealed interface J permits C {} > final class C implements J {} > > I i; > if (i instanceof J) {} // Error, only instance of J is C > // which doesn?t implement I > > Example 4: > ---------- > > sealed interface I permits A {} > sealed interface J permits B {} > final class A implements I {} > final class B implements J {} > > I i; > if (i instanceof J) {} // Error, similar to above > > > Example 5: > ---------- > > non-sealed class C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Yes! > > Example 6: > ---------- > > non-sealed class C {} > sealed interface I permits A {} > final class A implements I {} > > C c; > if (c instanceof I) {} // Error > > Example 7: > ---------- > > final class C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Error > > Example 8: > ---------- > > final class C {} > sealed interface I permits D {} > final class D implements I {} > > C c; > if (c instanceof I) {} // Error > > Example 9: > ---------- > > sealed class C permits D {} > final class D extends C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Error > > Example 10: > ----------- > > sealed class C permits D {} > final class D {} > sealed interface I permits E {} > final class E {} > > C c; > if (c instanceof I) {} // Error > > Example 11: > ----------- > > non-sealed interface I {} > non-sealed class C {} > > I i; > if (i instanceof C) {} // Yes! > > Example 12: > ----------- > > non-sealed interface I {} > final class C {} > > I i; > if (i instanceof C) {} // Error > > Example 13: > ----------- > > non-sealed interface I {} > sealed class C permits D {} > final class D {} > > I i; > if (i instanceof C) {} // Error > > Example 14: > ----------- > > sealed interface I permits D {} > final class D {} > non-sealed class C {} > > I i; > if (i instanceof C) {} // Error > > Example 15: > ----------- > > sealed interface I permits D {} > final class D implements I {} > final class C {} > > I i; > if (i instanceof C) {} // Error > > Example 16: > ----------- > > sealed interface I permits D {} > final class D implements I {} > sealed class C permits E {} > final class E extends C {} > > I i; > if (i instanceof C) {} // Error > From gavin.bierman at oracle.com Tue Feb 18 16:35:03 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 18 Feb 2020 16:35:03 +0000 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> Message-ID: > On 18 Feb 2020, at 15:04, forax at univ-mlv.fr wrote: > > Hi Gavin, > > ----- Mail original ----- >> De: "Gavin Bierman" >> ?: "Remi Forax" >> Cc: "jan lahoda" , "amber-spec-experts" >> Envoy?: Mardi 18 F?vrier 2020 15:32:12 >> Objet: Re: Pattern Matching for instanceof (Preview 2) > >> >>> - must the identifier of a pattern argument be the same name as the >>> corresponding record component ? >>> To be coherent with the fact that constructors requires the same names. >> >> Absolutely not! Note this does mean that you can write confusing code: >> >> record Point(int x, int y) { } >> >> if (o instanceof Point(var y, var x)) { >> ? // y refers to x component, y refers to x component >> } >> >> (I?ll get my coat?) > > yes, that's why i ask, it leads to very confusing code, some languages don't allow this kind of code, > by example destructuring in JavaScript as a special syntax if you want to use different names. I appreciate this, but requiring you to use the record component name is not very friendly if you have repeated nested patterns, e.g. if (o instanceof Line(Point(int x, int y), Point(int x, int y))) // Error two occurrences of x and y! { ?} The only way around that would be to have explicit renaming operators, which is pretty ugly. Gavin From jonathan.gibbons at oracle.com Tue Feb 18 17:43:42 2020 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 18 Feb 2020 09:43:42 -0800 Subject: [sealed] Changes to type system In-Reply-To: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> References: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> Message-ID: I'd be curious to see how the proposed rules interact (if at all) with the accessibility of the subtypes, and accessibility of sealed subtypes in particular. -- Jon On 2/18/20 7:47 AM, Gavin Bierman wrote: > Dear Experts: > > One aspect of sealed types that we have not discussed before, is that it > suggests a change in the type system. > > This change regards conversions used in casting contexts. For example, in Java > right now: > > interface I {} > class C {} // does not implement I > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > This compiles even though it is *currently* not possible for a C object to > implement the interface I. Of course, it might be, for example: > > class B extends C implements I {} > > test(new B()); > // Prints "It's an I" > > So, the conversion rules capture "open extensibility"; i.e. the Java type system > does not assume a closed world, classes and interfaces could be extended, and > casting conversions compile to runtime tests, so we can safely be flexible. > > However, at the other end of the spectrum the conversion rules do address > the case where a class can *not* be extended, i.e. when it is a *final* class. > > final class C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > The method test fails to compile, as the compiler knows that there can be no > subclass of C, so as C does not implement I then it is never possible for a C > value to implement I. This is a compile-time error. > > But what about if C is not final, but *sealed*? Given that its direct subclasses > are explicitly enumerated, and - by the definition of being sealed - in the same > module, we would surely expect the compiler to look to see if it can spot a > similar compile-time error. Consider the following code: > > interface I {} > sealed class C permits D {} > final class D extends C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > Class C does not implement I, and is not final - so by the old rules we might > conclude that there is a conversion - but it is sealed. There is one permitted > direct subclass of C: D. By definition of sealed types, D must be either final, > sealed or non-sealed. In this example, all the direct subclasses of C are final > and do not implement I, so in fact we can safely reject this program, as there > cannot be a subtype of C that implements I. > > In contrast, consider a similar program where one of the direct subclasses of > the sealed class is non-sealed: > > interface I {} > sealed class C permits D, E {} > non-sealed class D extends C {} > final class E extends C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > This is type correct as it is possible for a subtype of the non-sealed type D to > implement I. > > The trick is to extend the notion of allowed narrowing reference conversion (JLS > 5.1.6.1) to follow the sealed type declarations. I'll spare you the gory details > in this email - they will appear in the JLS draft appearing soon (!) - but I > wanted to check that this extension to the type system seems reasonable. > Obviously it will be putting more strain on the type checker. Is everyone happy > with this extension? > > Thanks, > Gavin > > > PS: Some further examples for your amusement: > > Example 1: > ---------- > > non-sealed interface I {} > non-sealed interface J {} > > I i; > if (i instanceof J) {} // Yes! > > Example 2: > ---------- > > sealed interface I permits C {} > final class C implements I {} > non-sealed interface J {} > > I i; > if (i instanceof J) {} // Error, only instance of I is C > // Which doesn?t implement J > > Example 3: > ---------- > > non-sealed interface I {} > sealed interface J permits C {} > final class C implements J {} > > I i; > if (i instanceof J) {} // Error, only instance of J is C > // which doesn?t implement I > > Example 4: > ---------- > > sealed interface I permits A {} > sealed interface J permits B {} > final class A implements I {} > final class B implements J {} > > I i; > if (i instanceof J) {} // Error, similar to above > > > Example 5: > ---------- > > non-sealed class C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Yes! > > Example 6: > ---------- > > non-sealed class C {} > sealed interface I permits A {} > final class A implements I {} > > C c; > if (c instanceof I) {} // Error > > Example 7: > ---------- > > final class C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Error > > Example 8: > ---------- > > final class C {} > sealed interface I permits D {} > final class D implements I {} > > C c; > if (c instanceof I) {} // Error > > Example 9: > ---------- > > sealed class C permits D {} > final class D extends C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Error > > Example 10: > ----------- > > sealed class C permits D {} > final class D {} > sealed interface I permits E {} > final class E {} > > C c; > if (c instanceof I) {} // Error > > Example 11: > ----------- > > non-sealed interface I {} > non-sealed class C {} > > I i; > if (i instanceof C) {} // Yes! > > Example 12: > ----------- > > non-sealed interface I {} > final class C {} > > I i; > if (i instanceof C) {} // Error > > Example 13: > ----------- > > non-sealed interface I {} > sealed class C permits D {} > final class D {} > > I i; > if (i instanceof C) {} // Error > > Example 14: > ----------- > > sealed interface I permits D {} > final class D {} > non-sealed class C {} > > I i; > if (i instanceof C) {} // Error > > Example 15: > ----------- > > sealed interface I permits D {} > final class D implements I {} > final class C {} > > I i; > if (i instanceof C) {} // Error > > Example 16: > ----------- > > sealed interface I permits D {} > final class D implements I {} > sealed class C permits E {} > final class E extends C {} > > I i; > if (i instanceof C) {} // Error > From jonathan.gibbons at oracle.com Tue Feb 18 19:11:39 2020 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Tue, 18 Feb 2020 11:11:39 -0800 Subject: [records] Summary so far In-Reply-To: References: Message-ID: On 2/18/20 7:19 AM, Gavin Bierman wrote: > Q6. @deprecated > > Should we allow record components to be marked as @deprecated? > > A: We don't want to add any additional support for @deprecated beyond the > fact that it is an annotation and it can be inspected via reflection. The wording here could be improved. `@deprecated` is a standard javadoc tag. It is not an annotation.? It goes along with the @Deprecated annotation. We should support the annotation, and support the tag in documentation as an adjunct to the annotation, but the tag alone should not imply deprecation. In the context of records, neither the annotation nor the tag should imply the `Deprecated` attribute in the class file. --Jon From vicente.romero at oracle.com Mon Feb 24 22:53:31 2020 From: vicente.romero at oracle.com (Vicente Romero) Date: Mon, 24 Feb 2020 17:53:31 -0500 Subject: [records] propogating modifiers for implicit methods In-Reply-To: References: Message-ID: Hi Manoj, In the current implementation methods `equals` and `hashCode` are final regardless of the corresponding record being explicitly of implicitly final. The fact that `toString` is not final is just a lack of consistency that should be fixed but we should probably decide what the spec should say about this first and then do the same for all the implicitly generated methods. In the case of `strictfp` the spec says in section `8.1.1.3 strictfp Classes`: .... This implies that all methods declared in the class, and all nested types declared in the class, are implicitly strictfp . .... so this is not related to records, as every class with the `strictfp` modifier applied will propagate it down to all its members. Thanks, Vicente On 2/21/20 1:24 AM, Manoj Palat wrote: > Hi, > ?(a) Given a record, ?recordR(inta){}, I see the (implicit) final > modifiers propagated to implicit methods hashCode() and equals() > [javap output] > > public *final* boolean equals(java.lang.Object); > > ?However, toString() does not get the same -> > > public java.lang.String toString(); > > (b)? Adding an explicit modifier, say strictfp adds this to all three > > *strictfp**record*R(*int*a){} > > public strictfp java.lang.String toString(); > > public final strictfp int hashCode(); > > public final strictfp boolean equals(java.lang.Object); > > I didn't see this explicitly specified in the Records JLS -> > http://cr.openjdk.java.net/~gbierman/jep359/jep359-20200115/specs/records-jls.html#jls-8.10.3 > Spec needs change? Or is there a newer version of spec ? > Regards, > Manoj > From maurizio.cimadamore at oracle.com Tue Feb 25 11:08:27 2020 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 25 Feb 2020 11:08:27 +0000 Subject: [sealed] Changes to type system In-Reply-To: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> References: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> Message-ID: Hi Gavin, the proposal makes sense to me - it seems like enhancing "side-cast" conversion rules to take sealed-ness into account is a natural extension of what we have; I'm not too worried about compiler performances; cast conversion is already a pretty complex routine as far as type relationships go, I don't see much here which can make it much worse, esp. if we consider the nightmare-ish stuff that javac currently does to rule out casts between provably disjoint generic types - where the notion of disjoint-ness is different from the simple one used by the spec and leads to much deeper checks. What I wanted to bring to your consideration is something that I've been pondering over the last few days - let's imagine something like this: sealed interface A permits Impl sealed interface B permits Impl Let's imagine that: * Both A and B are defined in exported packages of a module M * Impl is defined in a non-exported package of M * In other words, two separate interfaces share the same (hidden) implementation class I guess that, if we enhance cast conversion as you describe, casting A into B (and vice-versa) would be allowed by javac (there is in fact one type which implements both A and B), right? But if that's the case, I have to admit that I find it a bit awkward that I can use javac to probe sealed interfaces to see which might share a common implementation class, even if that implementation class is out of my reach and hidden behind module boundaries. In other words, while with the rules we have now, the user can always "see" why a cast has succeeded or fail, with these new rules, sometimes a cast can (statically) be rejected or not depending on details which might be unavailable to the site where the cast operation occurs. I wonder - should javac "stop" looking, and avoid descending into subtypes which are not visible from the use site (e.g. consider A and B as completely disjoint in the example above, if the cast occurs outside M?) What do you think? Maurizio On 18/02/2020 15:47, Gavin Bierman wrote: > Dear Experts: > > One aspect of sealed types that we have not discussed before, is that it > suggests a change in the type system. > > This change regards conversions used in casting contexts. For example, in Java > right now: > > interface I {} > class C {} // does not implement I > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > This compiles even though it is *currently* not possible for a C object to > implement the interface I. Of course, it might be, for example: > > class B extends C implements I {} > > test(new B()); > // Prints "It's an I" > > So, the conversion rules capture "open extensibility"; i.e. the Java type system > does not assume a closed world, classes and interfaces could be extended, and > casting conversions compile to runtime tests, so we can safely be flexible. > > However, at the other end of the spectrum the conversion rules do address > the case where a class can *not* be extended, i.e. when it is a *final* class. > > final class C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > The method test fails to compile, as the compiler knows that there can be no > subclass of C, so as C does not implement I then it is never possible for a C > value to implement I. This is a compile-time error. > > But what about if C is not final, but *sealed*? Given that its direct subclasses > are explicitly enumerated, and - by the definition of being sealed - in the same > module, we would surely expect the compiler to look to see if it can spot a > similar compile-time error. Consider the following code: > > interface I {} > sealed class C permits D {} > final class D extends C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > Class C does not implement I, and is not final - so by the old rules we might > conclude that there is a conversion - but it is sealed. There is one permitted > direct subclass of C: D. By definition of sealed types, D must be either final, > sealed or non-sealed. In this example, all the direct subclasses of C are final > and do not implement I, so in fact we can safely reject this program, as there > cannot be a subtype of C that implements I. > > In contrast, consider a similar program where one of the direct subclasses of > the sealed class is non-sealed: > > interface I {} > sealed class C permits D, E {} > non-sealed class D extends C {} > final class E extends C {} > > void test (C c) { > if (c instanceof I) > System.out.println("It's an I"); > } > > This is type correct as it is possible for a subtype of the non-sealed type D to > implement I. > > The trick is to extend the notion of allowed narrowing reference conversion (JLS > 5.1.6.1) to follow the sealed type declarations. I'll spare you the gory details > in this email - they will appear in the JLS draft appearing soon (!) - but I > wanted to check that this extension to the type system seems reasonable. > Obviously it will be putting more strain on the type checker. Is everyone happy > with this extension? > > Thanks, > Gavin > > > PS: Some further examples for your amusement: > > Example 1: > ---------- > > non-sealed interface I {} > non-sealed interface J {} > > I i; > if (i instanceof J) {} // Yes! > > Example 2: > ---------- > > sealed interface I permits C {} > final class C implements I {} > non-sealed interface J {} > > I i; > if (i instanceof J) {} // Error, only instance of I is C > // Which doesn?t implement J > > Example 3: > ---------- > > non-sealed interface I {} > sealed interface J permits C {} > final class C implements J {} > > I i; > if (i instanceof J) {} // Error, only instance of J is C > // which doesn?t implement I > > Example 4: > ---------- > > sealed interface I permits A {} > sealed interface J permits B {} > final class A implements I {} > final class B implements J {} > > I i; > if (i instanceof J) {} // Error, similar to above > > > Example 5: > ---------- > > non-sealed class C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Yes! > > Example 6: > ---------- > > non-sealed class C {} > sealed interface I permits A {} > final class A implements I {} > > C c; > if (c instanceof I) {} // Error > > Example 7: > ---------- > > final class C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Error > > Example 8: > ---------- > > final class C {} > sealed interface I permits D {} > final class D implements I {} > > C c; > if (c instanceof I) {} // Error > > Example 9: > ---------- > > sealed class C permits D {} > final class D extends C {} > non-sealed interface I {} > > C c; > if (c instanceof I) {} // Error > > Example 10: > ----------- > > sealed class C permits D {} > final class D {} > sealed interface I permits E {} > final class E {} > > C c; > if (c instanceof I) {} // Error > > Example 11: > ----------- > > non-sealed interface I {} > non-sealed class C {} > > I i; > if (i instanceof C) {} // Yes! > > Example 12: > ----------- > > non-sealed interface I {} > final class C {} > > I i; > if (i instanceof C) {} // Error > > Example 13: > ----------- > > non-sealed interface I {} > sealed class C permits D {} > final class D {} > > I i; > if (i instanceof C) {} // Error > > Example 14: > ----------- > > sealed interface I permits D {} > final class D {} > non-sealed class C {} > > I i; > if (i instanceof C) {} // Error > > Example 15: > ----------- > > sealed interface I permits D {} > final class D implements I {} > final class C {} > > I i; > if (i instanceof C) {} // Error > > Example 16: > ----------- > > sealed interface I permits D {} > final class D implements I {} > sealed class C permits E {} > final class E extends C {} > > I i; > if (i instanceof C) {} // Error > From brian.goetz at oracle.com Tue Feb 25 14:22:58 2020 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 25 Feb 2020 09:22:58 -0500 Subject: [sealed] Changes to type system In-Reply-To: References: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> Message-ID: <9a6f1a52-8c3f-af6a-f2ac-603715efafa6@oracle.com> Don't we have a similar problem with non-accessible supertypes and inference?? If I have: ??? private abstract class A { } ??? public class B extends A { } ??? public class C extends A { } Won't I infer LUB(B,C) = A, rather than Object? On 2/25/2020 6:08 AM, Maurizio Cimadamore wrote: > > But if that's the case, I have to admit that I find it a bit awkward > that I can use javac to probe sealed interfaces to see which might > share a common implementation class, even if that implementation class > is out of my reach and hidden behind module boundaries. In other > words, while with the rules we have now, the user can always "see" why > a cast has succeeded or fail, with these new rules, sometimes a cast > can (statically) be rejected or not depending on details which might > be unavailable to the site where the cast operation occurs. I wonder - > should javac "stop" looking, and avoid descending into subtypes which > are not visible from the use site (e.g. consider A and B as completely > disjoint in the example above, if the cast occurs outside M?) From maurizio.cimadamore at oracle.com Tue Feb 25 17:30:19 2020 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 25 Feb 2020 17:30:19 +0000 Subject: [sealed] Changes to type system In-Reply-To: <9a6f1a52-8c3f-af6a-f2ac-603715efafa6@oracle.com> References: <0FD47870-FF2D-4A3D-85EA-F03ECAE73847@oracle.com> <9a6f1a52-8c3f-af6a-f2ac-603715efafa6@oracle.com> Message-ID: <18d33eb2-b5e1-9b98-9239-fefe16e8b7cd@oracle.com> I agree that we can leak types in other circumstances - I'm not sure that the potential for source compatibility breakages is the same though. Maurizio On 25/02/2020 14:22, Brian Goetz wrote: > Don't we have a similar problem with non-accessible supertypes and > inference?? If I have: > > ??? private abstract class A { } > ??? public class B extends A { } > ??? public class C extends A { } > > Won't I infer LUB(B,C) = A, rather than Object? > > On 2/25/2020 6:08 AM, Maurizio Cimadamore wrote: >> >> But if that's the case, I have to admit that I find it a bit awkward >> that I can use javac to probe sealed interfaces to see which might >> share a common implementation class, even if that implementation >> class is out of my reach and hidden behind module boundaries. In >> other words, while with the rules we have now, the user can always >> "see" why a cast has succeeded or fail, with these new rules, >> sometimes a cast can (statically) be rejected or not depending on >> details which might be unavailable to the site where the cast >> operation occurs. I wonder - should javac "stop" looking, and avoid >> descending into subtypes which are not visible from the use site >> (e.g. consider A and B as completely disjoint in the example above, >> if the cast occurs outside M?) > From forax at univ-mlv.fr Fri Feb 28 11:46:10 2020 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 28 Feb 2020 12:46:10 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> Message-ID: <377333560.658035.1582890370911.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Gavin Bierman" > ?: "Remi Forax" > Cc: "jan lahoda" , "amber-spec-experts" > Envoy?: Mardi 18 F?vrier 2020 17:35:03 > Objet: Re: Pattern Matching for instanceof (Preview 2) >> On 18 Feb 2020, at 15:04, forax at univ-mlv.fr wrote: >> >> Hi Gavin, >> >> ----- Mail original ----- >>> De: "Gavin Bierman" >>> ?: "Remi Forax" >>> Cc: "jan lahoda" , "amber-spec-experts" >>> >>> Envoy?: Mardi 18 F?vrier 2020 15:32:12 >>> Objet: Re: Pattern Matching for instanceof (Preview 2) >> >>> >>>> - must the identifier of a pattern argument be the same name as the >>>> corresponding record component ? >>>> To be coherent with the fact that constructors requires the same names. >>> >>> Absolutely not! Note this does mean that you can write confusing code: >>> >>> record Point(int x, int y) { } >>> >>> if (o instanceof Point(var y, var x)) { >>> ? // y refers to x component, y refers to x component >>> } >>> >>> (I?ll get my coat?) >> >> yes, that's why i ask, it leads to very confusing code, some languages don't >> allow this kind of code, >> by example destructuring in JavaScript as a special syntax if you want to use >> different names. > > I appreciate this, but requiring you to use the record component name is not > very friendly if you have repeated nested patterns, e.g. > > if (o instanceof Line(Point(int x, int y), Point(int x, int y))) // Error two > occurrences of x and y! > { ?} > > The only way around that would be to have explicit renaming operators, which is > pretty ugly. yes, very good point. > > Gavin R?mi From forax at univ-mlv.fr Fri Feb 28 11:50:29 2020 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 28 Feb 2020 12:50:29 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> Message-ID: <1999135022.659177.1582890629787.JavaMail.zimbra@u-pem.fr> > De: "Gavin Bierman" > ?: "Remi Forax" > Cc: "jan lahoda" , "amber-spec-experts" > > Envoy?: Mardi 18 F?vrier 2020 16:16:40 > Objet: Re: Pattern Matching for instanceof (Preview 2) >> On 18 Feb 2020, at 15:04, [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] >> wrote: >> Hi Gavin, >> ----- Mail original ----- >>> De: "Gavin Bierman" < [ mailto:gavin.bierman at oracle.com | >>> gavin.bierman at oracle.com ] > >>> ?: "Remi Forax" < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] > >>> Cc: "jan lahoda" < [ mailto:jan.lahoda at oracle.com | jan.lahoda at oracle.com ] >, >>> "amber-spec-experts" < [ mailto:amber-spec-experts at openjdk.java.net | >>> amber-spec-experts at openjdk.java.net ] > >>> Envoy?: Mardi 18 F?vrier 2020 15:32:12 >>> Objet: Re: Pattern Matching for instanceof (Preview 2) >>> [Just circling back to this, as I added a note about the grammar to the JEP >>> page?] >>>> On 6 Feb 2020, at 20:38, Remi Forax < [ mailto:forax at univ-mlv.fr | >>>> forax at univ-mlv.fr ] > wrote: >>>> [moved to amber-spec] >>>> ----- Mail original ----- >>>>> De: "jan lahoda" < [ mailto:jan.lahoda at oracle.com | jan.lahoda at oracle.com ] > >>>>> ?: "amber-dev" < [ mailto:amber-dev at openjdk.java.net | >>>>> amber-dev at openjdk.java.net ] > >>>>> Envoy?: Jeudi 6 F?vrier 2020 21:18:52 >>>>> Objet: Pattern Matching for instanceof (Preview 2) >>>>> Hi, >>>>> Thanks to Gavin, Brian and Alex, there is a new draft JEP for Pattern >>>>> Matching for instanceof (Preview 2): >>>>> [ https://bugs.openjdk.java.net/browse/JDK-8235186 | >>>>> https://bugs.openjdk.java.net/browse/JDK-8235186 ] >>>>> Any feedback on the JEP is more than welcome! >>>>> Thanks, >>>>> Jan >>>> so the difference with the previous preview is that deconstruction is added. >>> That is correct. >>>> I see two questions: >>>> - the grammar allows to mix var and non-var for a given reference type, i think >>>> that should only permitted if the non var is a deconstruction itself ? >>> I don?t know what you mean here. There are two patterns, a type test pattern and >>> a deconstruction pattern. In v2 we propose to support deconstruction patterns >>> over record types *only*. A deconstruction pattern looks like this: Point(var >>> a, var b), i.e. all the components are either (recursively) deconstruction >>> patterns, or `var` , i.e. with no type needed. I added a note to >>> the JEP page pointing out that this is a starting point, and eventually we will >>> support other patterns in the argument position, specifically >>> ; hopefully in this release. >> Currently we don't support mixing var and non var in lambda parameters. >> So my question is: does this pattern Point(var x, int y) that mix a 'var' and an >> explicit type allowed or not ? > Aha. So, we?re not at that stage yet - this isn?t allowed by the spec as it > stands. This - and many other issues - is why I?m starting small? > Do you have a preference? I don't think it's a matter of preference, we want to support things like Rectangle(var p1, Point(var x, var y)) For the type pattern Rectangle(...), there is a mix between var and non var, no ? > Gavin R?mi From forax at univ-mlv.fr Fri Feb 28 11:52:23 2020 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 28 Feb 2020 12:52:23 +0100 (CET) Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <7e3a649d-62a3-2a31-d755-9282272e9c4c@oracle.com> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> <7e3a649d-62a3-2a31-d755-9282272e9c4c@oracle.com> Message-ID: <835624742.659453.1582890743937.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Brian Goetz" > ?: "Remi Forax" , "Gavin Bierman" > Cc: "amber-spec-experts" , "jan lahoda" > Envoy?: Mardi 18 F?vrier 2020 16:14:57 > Objet: Re: Pattern Matching for instanceof (Preview 2) >>> I don?t know what you mean here. There are two patterns, a type test pattern and >>> a deconstruction pattern. In v2 we propose to support deconstruction patterns >>> over record types *only*. A deconstruction pattern looks like this: Point(var >>> a, var b), i.e. all the components are either (recursively) deconstruction >>> patterns, or `var` , i.e. with no type needed. I added a note to >>> the JEP page pointing out that this is a starting point, and eventually we will >>> support other patterns in the argument position, specifically >>> ; hopefully in this release. >> Currently we don't support mixing var and non var in lambda parameters. >> So my question is: does this pattern Point(var x, int y) that mix a 'var' and an >> explicit type allowed or not ? > > Unequivocal "yes".?? There is a universe of patterns.? Some might be > disallowed in certain contexts (e.g., `instanceof var x` seems kind of > silly), but once we decide on the set of patterns allowable in which > contexts, any pattern can be nested inside a deconstruction pattern. > > The `var x` pattern can equally be thought of as inference for a total > type pattern, or an "any" pattern; they are semantically equivalent. > > If you're asking "but why can I not mix them in a lambda", the answer > is: because we don't support partial inference in lambdas at this time. > We could, and we might someday.? (If you're suggesting that the > consistency between the two superficially-related forms is the most > important consideration here, I would disagree.) with a record, there is no real inference, but when you will have several deconstructors, we will need inference, right ? R?mi From forax at univ-mlv.fr Fri Feb 28 12:07:15 2020 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 28 Feb 2020 13:07:15 +0100 (CET) Subject: [records] Summary so far In-Reply-To: References: Message-ID: <1869961828.663033.1582891635044.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Gavin Bierman" > ?: "amber-spec-experts" > Envoy?: Mardi 18 F?vrier 2020 16:19:48 > Objet: [records] Summary so far > Dear Experts: > > In [1] Brian asked for comments on some remaining design decisions concerning > records (and asked for any new ones that you'd like to raise). > > First, thank you for your feedback so far! I have been through the threads, and > tried to summarize the question and the current status below. Of course, > these decisions are not set in stone, but the point of this email is to warn you > that they are hardening :-) So, if you disagree, or would like further > discussion, *now* is the time to speak up! > > > Q1. Should the distinguished supertype of records java.lang.Record be > renamed? > > [Since the original post, it seems that inline types will be able to inherit > from abstract classes.] > > Is the name "Record" a good one? It has good clash > potential :-) possible alternatives are RecordClass, or AbstractRecord? > > A: No consensus so far. Given that Enum is not AbstractEnum so I'm ok with java.lang.Record > > Q2. Accessibilty of mandated members. > > Currently the mandated members are public regardless of the accessibility of > the record type. What should be the default accessibility for record > members? > > A: Currently the most popular proposal is that mandated members get > accessibility of the record type. Other members get package level > accessibility as per a regular class. (Note: it should be legal for explicit > declarations of mandated members to specify something _more_ accessible > (same rules as overriding.) ) +1 > > Q3. Nesting. > > A: We are working on a new spec that removes a lot of restriction regarding > nested classes/records. +1 > > Q4. Abstract records. > > Should we allow the declaration of abstract classes, possibly supporting > some form of record subtyping? > > A: No support for this. I agree, no support. > > Q5. Deconstruction patterns. > > A: We will be proposing deconstruction patterns in the patterns v2 preview. This one worry me because we are proposing deconstruction patterns without introducing deconstruction patterns for declaring local variable at the same time. so p instanceof Point(var x, var y) is ok but Point(var x, var y) = p; is not. I understand that in term of JEP adding deconstruction patterns in the patterns to the JEP seems to be a small refinement but - i would like to be sure that the same syntax can be used for local variables declaration, do you have a grammar issue here ? - i don't want to see people abusing of instanceof has a destructuring construct because we don't propose a destructuring one at the same time. > > Q6. @deprecated > > Should we allow record components to be marked as @deprecated? > > A: We don't want to add any additional support for @deprecated beyond the > fact that it is an annotation and it can be inspected via reflection. Fine, this as been settled (at least for me). > > Q7. .equals and .toString are slow. > > Remi [2] points out that the current implementations of .equals and > .toString are slow. > > A: We will look into this. .equals() and .hashCode() are not slow, .toString() is slow :) > > Q8. Translation strategy. > > John [3] suggested changing the compilation strategy of records so we can > future-proof the evolution of members from the record supertype. > > A: No change. Q8 and a half, I've sent my own proposal to slightly change the compilation strategy of the Object methods to use reflection on the Record attribute instead of asking to send constant method handles. > > Q9. Hashing. > > John [4] proposed weakening of the .hashCode spec. > > A: Agreed. John has written candidate text [5]. I agree > > Q10. Special annotation for explicit declaration of accessors. > > Tagir [6] proposes a new `@RecordAccessor` annotation to mark explicit > accessors, much as `@Override` is used to mark method overrides. > > A: Rather than introduce a new accessor, we will consider extending the > meaning of the `@Override` annotation to include this case. I agree, @Override is fine here even if it's not a real override (using @Override on an asbtract method of an interface is not a real override too so @Override doesn't mean @Override since Java 6 anyway). > > Q11. Changing the spec of .toString method > > We should weaken the spec of the .toString method so it explicitly states > that the form of the string produced is subject to change and can not be > relied upon. > > A: Agreed. I agree. > > Q12. Transactional methods > > Canonical constructors are an instance of a general pattern where a set of > variables are in scope for a given block, and assigned values at the end. > This could be a useful abstraction to be given first-class representation. > > A: No change. More research needed. yes ! > > Q13. Factory methods instead of constructors. > > Should "new R(v1, ..., vn)" be compiled to a factory method, to allow > future-proofing with inline types? > > A: No change for now. yes ! > > Thanks for your comments and discussions so far. If you disagree with anything > written here, please reply! > > Thanks, > Gavin R?mi > > > [1] > https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001913.html > [2] > https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001943.html > [3] > https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001937.html > [4] > https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001935.html > [5] http://cr.openjdk.java.net/~jrose/draft/record-contract > [6] > https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-January/001931.html From gavin.bierman at oracle.com Fri Feb 28 12:25:37 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 28 Feb 2020 12:25:37 +0000 Subject: [sealed] Draft Language Spec available Message-ID: <968C30B0-A4A3-4D36-B25B-595D4D0BAE24@oracle.com> The next draft language spec for JEP 360 (Sealed Types) is available at: http://cr.openjdk.java.net/~gbierman/jep360/latest/ This version reflects the changes to the type system I mentioned [1], along with a number of other changes. We?d appreciate further comments on this in particular (along with anything else). Thanks, Gavin [1] https://mail.openjdk.java.net/pipermail/amber-spec-experts/2020-February/002018.html From gavin.bierman at oracle.com Fri Feb 28 13:06:04 2020 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Fri, 28 Feb 2020 13:06:04 +0000 Subject: Pattern Matching for instanceof (Preview 2) In-Reply-To: <835624742.659453.1582890743937.JavaMail.zimbra@u-pem.fr> References: <8d30d504-dd25-de1f-a54d-1a80fe1f6c5d@oracle.com> <1446466454.577367.1581021509341.JavaMail.zimbra@u-pem.fr> <8FBE91DA-A349-46C8-9286-1528AD09853B@oracle.com> <868621508.813629.1582038287047.JavaMail.zimbra@u-pem.fr> <7e3a649d-62a3-2a31-d755-9282272e9c4c@oracle.com> <835624742.659453.1582890743937.JavaMail.zimbra@u-pem.fr> Message-ID: <045BDF46-6181-4A8D-B520-9CBFE0639F51@oracle.com> > On 28 Feb 2020, at 11:52, forax at univ-mlv.fr wrote: > > ----- Mail original ----- >> De: "Brian Goetz" >> ?: "Remi Forax" , "Gavin Bierman" >> Cc: "amber-spec-experts" , "jan lahoda" >> Envoy?: Mardi 18 F?vrier 2020 16:14:57 >> Objet: Re: Pattern Matching for instanceof (Preview 2) > >>>> I don?t know what you mean here. There are two patterns, a type test pattern and >>>> a deconstruction pattern. In v2 we propose to support deconstruction patterns >>>> over record types *only*. A deconstruction pattern looks like this: Point(var >>>> a, var b), i.e. all the components are either (recursively) deconstruction >>>> patterns, or `var` , i.e. with no type needed. I added a note to >>>> the JEP page pointing out that this is a starting point, and eventually we will >>>> support other patterns in the argument position, specifically >>>> ; hopefully in this release. >>> Currently we don't support mixing var and non var in lambda parameters. >>> So my question is: does this pattern Point(var x, int y) that mix a 'var' and an >>> explicit type allowed or not ? >> >> Unequivocal "yes". There is a universe of patterns. Some might be >> disallowed in certain contexts (e.g., `instanceof var x` seems kind of >> silly), but once we decide on the set of patterns allowable in which >> contexts, any pattern can be nested inside a deconstruction pattern. >> >> The `var x` pattern can equally be thought of as inference for a total >> type pattern, or an "any" pattern; they are semantically equivalent. >> >> If you're asking "but why can I not mix them in a lambda", the answer >> is: because we don't support partial inference in lambdas at this time. >> We could, and we might someday. (If you're suggesting that the >> consistency between the two superficially-related forms is the most >> important consideration here, I would disagree.) > > > with a record, there is no real inference, but when you will have several deconstructors, we will need inference, right ? > That?s exactly it! We just want to make sure we don?t bake something in that won?t work for more general overloaded deconstructors. Gavin