From angelos.bimpoudis at oracle.com Thu Jan 26 10:36:53 2023 From: angelos.bimpoudis at oracle.com (Angelos Bimpoudis) Date: Thu, 26 Jan 2023 10:36:53 +0000 Subject: Draft JLS Spec about unnamed patterns and variables Message-ID: Dear experts, The first draft of the JLS spec about unnamed patterns and variables (https://openjdk.org/jeps/8294349) is available at: https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/ Comments very much welcomed! Angelos -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 26 13:16:15 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 26 Jan 2023 14:16:15 +0100 (CET) Subject: Draft JEP on Primitive types in patterns, instanceof, and switch Message-ID: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> > From: "Angelos Bimpoudis" > To: "amber-dev" > Sent: Thursday, January 26, 2023 10:48:47 AM > Subject: Draft JEP on Primitive types in patterns, instanceof, and switch > Hello all, > I would like to share this draft JEP with you about primitive types in patterns, > instanceof, and switch: > https://openjdk.org/jeps/8288476 > "Enhance pattern matching by allowing primitive types to appear anywhere in > patterns. Extend instanceof to support primitive types, and extend switch to > allow primitive constants as case labels." > Comments very much welcomed! > Many thanks, > Angelos I still think that the semantics proposed for pattern matching on primitive types is useless complexity with the perverse side effect of normalizing the usage of "default" in pattern matching (too many examples of this JEP are using "default") but we already discussed that. Allowing switching on double and float constants is just wrong. Rust is actually trying to remove that feature [ https://github.com/rust-lang/rust/issues/41255 | https://github.com/rust-lang/rust/issues/41255 ] I see no point to make the same mistake. Otherwise, the rest is fine. R?mi From forax at univ-mlv.fr Thu Jan 26 13:29:20 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 26 Jan 2023 14:29:20 +0100 (CET) Subject: Draft JLS Spec about unnamed patterns and variables In-Reply-To: References: Message-ID: <544050367.5820797.1674739760716.JavaMail.zimbra@u-pem.fr> > From: "Angelos Bimpoudis" > To: "amber-spec-experts" > Sent: Thursday, January 26, 2023 11:36:53 AM > Subject: Draft JLS Spec about unnamed patterns and variables > Dear experts, > The first draft of the JLS spec about unnamed patterns and variables > (https://openjdk.org/jeps/8294349) is available at: > https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/ > Comments very much welcomed! > Angelos In 14.14.2, "If the header contains an unnamed local variable declaration ( [ https://cr.openjdk.java.net/~abimpoudis/unnamed/unnamed-20230123/specs/unnamed-jls.html#jls-6.1 | 6.1 ] ) then #n is an automatically generated identifier that is distinct from any other identifiers (automatically generated or otherwise) that are in scope ( [ https://cr.openjdk.java.net/~abimpoudis/unnamed/unnamed-20230123/specs/unnamed-jls.html#jls-6.3 | 6.3 ] ) at the point where the enhanced for statement occurs. Otherwise #n is the Identifier ." why #n can not be '_' if the header contains an unnamed local variable ? The rest looks good. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From angelos.bimpoudis at oracle.com Thu Jan 26 13:55:31 2023 From: angelos.bimpoudis at oracle.com (Angelos Bimpoudis) Date: Thu, 26 Jan 2023 13:55:31 +0000 Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> Message-ID: Thanks for the quick reply. I think there is one important factor here. By quickly inspecting the issues in the links, IIUC, the semantics of floating-point constants there follow the semantics of ==?. So -0 and 0 compare equal there (e.g., https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182). The JEP follows the road of "representation equivalence" as described in https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq ________________________________ From: Remi Forax Sent: 26 January 2023 14:16 To: Angelos Bimpoudis Cc: amber-spec-experts Subject: [External] : Re: Draft JEP on Primitive types in patterns, instanceof, and switch > From: "Angelos Bimpoudis" > To: "amber-dev" > Sent: Thursday, January 26, 2023 10:48:47 AM > Subject: Draft JEP on Primitive types in patterns, instanceof, and switch > Hello all, > I would like to share this draft JEP with you about primitive types in patterns, > instanceof, and switch: > https://openjdk.org/jeps/8288476 > "Enhance pattern matching by allowing primitive types to appear anywhere in > patterns. Extend instanceof to support primitive types, and extend switch to > allow primitive constants as case labels." > Comments very much welcomed! > Many thanks, > Angelos I still think that the semantics proposed for pattern matching on primitive types is useless complexity with the perverse side effect of normalizing the usage of "default" in pattern matching (too many examples of this JEP are using "default") but we already discussed that. Allowing switching on double and float constants is just wrong. Rust is actually trying to remove that feature [ https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ | https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ ] I see no point to make the same mistake. Otherwise, the rest is fine. R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 26 14:25:36 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 26 Jan 2023 15:25:36 +0100 (CET) Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> Message-ID: <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> > From: "Angelos Bimpoudis" > To: "Remi Forax" > Cc: "amber-spec-experts" > Sent: Thursday, January 26, 2023 2:55:31 PM > Subject: Re: Draft JEP on Primitive types in patterns, instanceof, and switch > Thanks for the quick reply. > I think there is one important factor here. By quickly inspecting the issues in > the links, IIUC, the semantics of floating-point constants there follow the > semantics of == ?. So -0 and 0 compare equal there (e.g., [ > https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182 | > https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182 ] ). > The JEP follows the road of "representation equivalence" as described in [ > https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq > | > https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq > ] In terms of semantics Double::equals may be better than double == double, this seems to be the direction that Java is choosing (Valhhalla also used Double::equals for value types containing a double). But it means that introducing a "when" is not a valid refactoring case double 3.14 -> ... can not be refactored to case double x when x == 3.14 -> ... Most of my students thinks in terms of equivalence, breaking this kind of refactoring make the proposed semantics not intuitive. That's why i think it's better to not allow double/float constants, so people have to be explicit about the semantics they want. regards, R?mi > From: Remi Forax > Sent: 26 January 2023 14:16 > To: Angelos Bimpoudis > Cc: amber-spec-experts > Subject: [External] : Re: Draft JEP on Primitive types in patterns, instanceof, > and switch > > From: "Angelos Bimpoudis" > > To: "amber-dev" > > Sent: Thursday, January 26, 2023 10:48:47 AM > > Subject: Draft JEP on Primitive types in patterns, instanceof, and switch > > Hello all, > > I would like to share this draft JEP with you about primitive types in patterns, > > instanceof, and switch: > > [ https://openjdk.org/jeps/8288476 | https://openjdk.org/jeps/8288476 ] > > "Enhance pattern matching by allowing primitive types to appear anywhere in > > patterns. Extend instanceof to support primitive types, and extend switch to > > allow primitive constants as case labels." > > Comments very much welcomed! > > Many thanks, > > Angelos > I still think that the semantics proposed for pattern matching on primitive > types is useless complexity with the perverse side effect of normalizing the > usage of "default" in pattern matching (too many examples of this JEP are using > "default") but we already discussed that. > Allowing switching on double and float constants is just wrong. > Rust is actually trying to remove that feature > [ [ > https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ > | > https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ > ] | [ > https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ > | > https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ > ] ] > I see no point to make the same mistake. > Otherwise, the rest is fine. > R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu Jan 26 14:36:22 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 26 Jan 2023 09:36:22 -0500 Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> Message-ID: <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> Everything about floating point is difficult and fiddly and resists a one-size-fits-all treatment.? Joe recently did some work to characterize the various ways floats can be compared -- representational equivalence, bitwise equivalence, and the traditional `==`, and put these in the spec of Float/Double, so we would have a vocabulary to discuss them. The main differences between these treatments are the treatment of NaN and signed zeroes.? (And for $REASONS, there are multiple NaN bit patterns.) Representational equality means "same number", where all NaN values are the same.? Float::equals uses representational equality. Bitwise equality means "same bit pattern". The `==` operator says that 0 == -0 and that NaN is equal to nothing, not even itself. For comparing a variable to a constant, representational equality is the obvious interpretation; `case nnn` means "is it the number nnn".? This allows you to say `case NaN` and `case -0` and get the right answer (all of these relations agree on what to do about 1.0). For Valhalla's `==`, which we've decided means "substitutible" or "indistinguishable from", then bitwise equality is the obvious answer.? Its sad that these are all different, and each case requires getting experts in a room to hash it out, but that's life with floating point. Your claim about refactoring anomalies is not right; the refactoring you offer will work for your example which uses 3.14, because `==` agrees with r.e. at the "regular" floating point values.? Where it will fail is for NaN, as `==` has its own weird opinions about NaN.? But `== NaN` is intrinsically useless anyway, since it folds to false, and anyone who knows what NaN is already knows this (probably by having been bitten by it). On 1/26/2023 9:25 AM, forax at univ-mlv.fr wrote: > > > ------------------------------------------------------------------------ > > *From: *"Angelos Bimpoudis" > *To: *"Remi Forax" > *Cc: *"amber-spec-experts" > *Sent: *Thursday, January 26, 2023 2:55:31 PM > *Subject: *Re: Draft JEP on Primitive types in patterns, > instanceof, and switch > > Thanks for the quick reply. > > I think there is one important factor here. By quickly inspecting > the issues in the links, IIUC,?the semantics of floating-point > constants there follow the semantics of |==|?. So -0 and 0 compare > equal there (e.g., > https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182). > > > The JEP follows the road of "representation equivalence" as > described in > https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq > > > > In terms of semantics Double::equals may be better than double == > double, this seems to be the direction that Java is choosing > (Valhhalla also used Double::equals for value types containing a double). > > But it means that introducing a "when" is not a valid refactoring > ? case double 3.14 -> ... > can not be refactored to > ? case double x when x == 3.14 -> ... > > Most of my students thinks in terms of equivalence, breaking this kind > of refactoring make the proposed semantics not intuitive. > > That's why i think it's better to not allow double/float constants, so > people have to be explicit about the semantics they want. > > regards, > R?mi > > > > ------------------------------------------------------------------------ > *From:* Remi Forax > *Sent:* 26 January 2023 14:16 > *To:* Angelos Bimpoudis > *Cc:* amber-spec-experts > *Subject:* [External] : Re: Draft JEP on Primitive types in > patterns, instanceof, and switch > > From: "Angelos Bimpoudis" > > To: "amber-dev" > > Sent: Thursday, January 26, 2023 10:48:47 AM > > Subject: Draft JEP on Primitive types in patterns, instanceof, > and switch > > > Hello all, > > > I would like to share this draft JEP with you about primitive > types in patterns, > > instanceof, and switch: > > > https://openjdk.org/jeps/8288476 > > > "Enhance pattern matching by allowing primitive types to appear > anywhere in > > patterns. Extend instanceof to support primitive types, and > extend switch to > > allow primitive constants as case labels." > > > Comments very much welcomed! > > > Many thanks, > > Angelos > > I still think that the semantics proposed for pattern matching on > primitive types is useless complexity with the perverse side > effect of normalizing the usage of "default" in pattern matching > (too many examples of this JEP are using "default") but we already > discussed that. > > Allowing switching on double and float constants is just wrong. > Rust is actually trying to remove that feature > [ > https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ > | > https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ > ] > > I see no point to make the same mistake. > > Otherwise, the rest is fine. > > R?mi > -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 26 14:54:44 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 26 Jan 2023 15:54:44 +0100 (CET) Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> Message-ID: <2062695686.5944671.1674744884512.JavaMail.zimbra@u-pem.fr> > From: "Brian Goetz" > To: "Remi Forax" , "Angelos Bimpoudis" > > Cc: "amber-spec-experts" > Sent: Thursday, January 26, 2023 3:36:22 PM > Subject: Re: Draft JEP on Primitive types in patterns, instanceof, and switch > Everything about floating point is difficult and fiddly and resists a > one-size-fits-all treatment. Joe recently did some work to characterize the > various ways floats can be compared -- representational equivalence, bitwise > equivalence, and the traditional `==`, and put these in the spec of > Float/Double, so we would have a vocabulary to discuss them. > The main differences between these treatments are the treatment of NaN and > signed zeroes. (And for $REASONS, there are multiple NaN bit patterns.) > Representational equality means "same number", where all NaN values are the > same. Float::equals uses representational equality. > Bitwise equality means "same bit pattern". > The `==` operator says that 0 == -0 and that NaN is equal to nothing, not even > itself. > For comparing a variable to a constant, representational equality is the obvious > interpretation; `case nnn` means "is it the number nnn". This allows you to say > `case NaN` and `case -0` and get the right answer (all of these relations agree > on what to do about 1.0). > For Valhalla's `==`, which we've decided means "substitutible" or > "indistinguishable from", then bitwise equality is the obvious answer. Its sad > that these are all different, and each case requires getting experts in a room > to hash it out, but that's life with floating point. > Your claim about refactoring anomalies is not right; the refactoring you offer > will work for your example which uses 3.14, because `==` agrees with r.e. at > the "regular" floating point values. Where it will fail is for NaN, as `==` has > its own weird opinions about NaN. But `== NaN` is intrinsically useless anyway, > since it folds to false, and anyone who knows what NaN is already knows this > (probably by having been bitten by it). That why there is Double.isNaN(). The problem is that there are two semantics and it's not clear to me which one is the one the user want. The proposed semantics choose for the user, and use the representational equality. It works until it does not work, i.e. if the pattern matching is used in a computation for which the difference between 0 and -0 is important, by example in a division. Here we have the luxury to ask users to be explicit about the semantics they want, because pattern matching on floats/doubles will be rare, so not committing to a peculiar a semantics seems a better choice here. R?mi > On 1/26/2023 9:25 AM, [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] wrote: >>> From: "Angelos Bimpoudis" [ mailto:angelos.bimpoudis at oracle.com | >>> ] >>> To: "Remi Forax" [ mailto:forax at univ-mlv.fr | ] >>> Cc: "amber-spec-experts" [ mailto:amber-spec-experts at openjdk.org | >>> ] >>> Sent: Thursday, January 26, 2023 2:55:31 PM >>> Subject: Re: Draft JEP on Primitive types in patterns, instanceof, and switch >>> Thanks for the quick reply. >>> I think there is one important factor here. By quickly inspecting the issues in >>> the links, IIUC, the semantics of floating-point constants there follow the >>> semantics of == ?. So -0 and 0 compare equal there (e.g., [ >>> https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182 | >>> https://github.com/rust-lang/rust/issues/41620#issuecomment-300587182 ] ). >>> The JEP follows the road of "representation equivalence" as described in [ >>> https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq >>> | >>> https://download.java.net/java/early_access/jdk20/docs/api/java.base/java/lang/Double.html#fpNumericalEq >>> ] >> In terms of semantics Double::equals may be better than double == double, this >> seems to be the direction that Java is choosing (Valhhalla also used >> Double::equals for value types containing a double). >> But it means that introducing a "when" is not a valid refactoring >> case double 3.14 -> ... >> can not be refactored to >> case double x when x == 3.14 -> ... >> Most of my students thinks in terms of equivalence, breaking this kind of >> refactoring make the proposed semantics not intuitive. >> That's why i think it's better to not allow double/float constants, so people >> have to be explicit about the semantics they want. >> regards, >> R?mi >>> From: Remi Forax [ mailto:forax at univ-mlv.fr | ] >>> Sent: 26 January 2023 14:16 >>> To: Angelos Bimpoudis [ mailto:angelos.bimpoudis at oracle.com | >>> ] >>> Cc: amber-spec-experts [ mailto:amber-spec-experts at openjdk.org | >>> ] >>> Subject: [External] : Re: Draft JEP on Primitive types in patterns, instanceof, >>> and switch >>>> From: "Angelos Bimpoudis" [ mailto:angelos.bimpoudis at oracle.com | >>> > ] >>> > To: "amber-dev" [ mailto:amber-dev at openjdk.org | ] >>> > Sent: Thursday, January 26, 2023 10:48:47 AM >>> > Subject: Draft JEP on Primitive types in patterns, instanceof, and switch >>> > Hello all, >>> > I would like to share this draft JEP with you about primitive types in patterns, >>> > instanceof, and switch: >>> > [ https://openjdk.org/jeps/8288476 | https://openjdk.org/jeps/8288476 ] >>> > "Enhance pattern matching by allowing primitive types to appear anywhere in >>> > patterns. Extend instanceof to support primitive types, and extend switch to >>> > allow primitive constants as case labels." >>> > Comments very much welcomed! >>> > Many thanks, >>> > Angelos >>> I still think that the semantics proposed for pattern matching on primitive >>> types is useless complexity with the perverse side effect of normalizing the >>> usage of "default" in pattern matching (too many examples of this JEP are using >>> "default") but we already discussed that. >>> Allowing switching on double and float constants is just wrong. >>> Rust is actually trying to remove that feature >>> [ [ >>> https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ >>> | >>> https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ >>> ] | [ >>> https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ >>> | >>> https://urldefense.com/v3/__https://github.com/rust-lang/rust/issues/41255__;!!ACWV5N9M2RV99hQ!NfJ7KspB447oMGi0NoEyXC6s_w3vD1N-SBu5hiD4kMVAkmwDWPNbymH83iOnrkakPoayD6vwGwuB5NvedJfjH9LU$ >>> ] ] >>> I see no point to make the same mistake. >>> Otherwise, the rest is fine. >>> R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From guy.steele at oracle.com Thu Jan 26 15:25:16 2023 From: guy.steele at oracle.com (Guy Steele) Date: Thu, 26 Jan 2023 15:25:16 +0000 Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> Message-ID: On Jan 26, 2023, at 9:36 AM, Brian Goetz > wrote: ... For comparing a variable to a constant, representational equality is the obvious interpretation; `case nnn` means "is it the number nnn". This allows you to say `case NaN` and `case -0` and get the right answer (all of these relations agree on what to do about 1.0). Careful: I think you had better say ?case -0.0?; otherwise the constant expression ?-0? will be reduced to ?0? and only then converted to floating-point representation, producing +0.0. Yes, floating-point is VERY fiddly. ?Guy -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Thu Jan 26 15:30:49 2023 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 26 Jan 2023 16:30:49 +0100 (CET) Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> Message-ID: <1364784248.5989771.1674747049108.JavaMail.zimbra@u-pem.fr> > From: "Guy Steele" > To: "Brian Goetz" > Cc: "Remi Forax" , "Angelos Bimpoudis" > , "amber-spec-experts" > > Sent: Thursday, January 26, 2023 4:25:16 PM > Subject: Re: Draft JEP on Primitive types in patterns, instanceof, and switch >> On Jan 26, 2023, at 9:36 AM, Brian Goetz < [ mailto:brian.goetz at oracle.com | >> brian.goetz at oracle.com ] > wrote: >> ... >> For comparing a variable to a constant, representational equality is the obvious >> interpretation; `case nnn` means "is it the number nnn". This allows you to say >> `case NaN` and `case -0` and get the right answer (all of these relations agree >> on what to do about 1.0). > Careful: I think you had better say ? case -0.0 ?; otherwise the constant > expression ? -0 ? will be reduced to ? 0 ? and only then converted to > floating-point representation, producing +0.0 . > Yes, floating-point is VERY fiddly. As i read the current spec, case -0 is equivalent to case 0, and you can not have both of them in the same switch. > ?Guy R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From guy.steele at oracle.com Thu Jan 26 15:36:42 2023 From: guy.steele at oracle.com (Guy Steele) Date: Thu, 26 Jan 2023 15:36:42 +0000 Subject: Draft JLS Spec about unnamed patterns and variables In-Reply-To: References: Message-ID: On Jan 26, 2023, at 5:36 AM, Angelos Bimpoudis > wrote: Dear experts, The first draft of the JLS spec about unnamed patterns and variables (https://openjdk.org/jeps/8294349) is available at: https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/ Comments very much welcomed! Angelos I did a fairly quick read-through, but with focused attention on the rules for switch-label dominance, and it looks pretty good to me. ?Guy -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu Jan 26 16:04:42 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 26 Jan 2023 11:04:42 -0500 Subject: Draft JEP on Primitive types in patterns, instanceof, and switch In-Reply-To: References: <345951843.5806933.1674738975706.JavaMail.zimbra@u-pem.fr> <226409753.5913335.1674743136668.JavaMail.zimbra@u-pem.fr> <7e218f85-0181-bb00-ed5a-b9d3029c2c4c@oracle.com> Message-ID: <03241935-d564-c7e0-9577-52efc3935a92@oracle.com> Yes, pardon my quick typing. More specifically, a case constant is not a _constant pattern_ (at least, not yet), it is just a constant case label. Constants are typed, and they carray both a type match and a value match.? When you say ??? case 0 this is a constant for an int, and doesn't match a floating point zero (if the match target is `float`, it won't even compile.)? Similarly, `case 0.0` is a constant for a float, and is not applicable to a match target of int.? (We do have the usual tolerance for matching int constants to shorter int types, as before.) We may generalize these to constant patterns in the future, but right now, these are constant case labels and their semantics are derived from that of existing case labels. On 1/26/2023 10:25 AM, Guy Steele wrote: > > >> On Jan 26, 2023, at 9:36 AM, Brian Goetz wrote: >> >> ... >> >> For comparing a variable to a constant, representational equality is >> the obvious interpretation; `case nnn` means "is it the number nnn".? >> This allows you to say `case NaN` and `case -0` and get the right >> answer (all of these relations agree on what to do about 1.0). > > Careful: I think you had better say ?case -0.0?; otherwise the > constant expression ?-0? will be reduced to ?0? and only then > converted to floating-point representation, producing +0.0. > > Yes, floating-point is VERY fiddly. > > ?Guy > -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Thu Jan 26 19:33:01 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 26 Jan 2023 14:33:01 -0500 Subject: Draft JLS Spec about unnamed patterns and variables In-Reply-To: References: Message-ID: <6a57f58c-6f91-612b-ec48-9213e85e168c@oracle.com> Small wording nit...? in "an unnamed declaration can be used in place of the following declarations" I'm not sure "in place of" is the right wording; I think you may just want to say "in", since the grammar permits it in all of these places.? (What you're really doing here is signalling that there are places the grammar allows it, but the semantics do not; you are going to call these out individually in the appropriate places.) Similar for the second "in place of" in this section. In 14.11.1, I might refactor the text a little further.? The second sentence of the first paragraph below is about case constants only, but now comes after you talk about case patterns or case constants: > A|case|label has either one or more|case|constants, ora*one or > more*|case|pattern*s*. Every|case|constant must be either (1) > the|null|literal, (2) a constant expression (15.29 > ), > or (3) the name of an enum constant (8.9.1 > ); > otherwise a compile-time error occurs. A|case|label that has > a|null||case|constant may have an optional|default|. > > It is a compile-time error if for any|case|label with more than > one|case|patterns, any of its|case|patterns declares one or more > pattern variables. > I suggest: A|case|label has either one or more|case|constants, ora*one or more*|case|pattern*s*. /For a case label with case constants, /every|case|constant must be either (1) the|null|literal, (2) a constant expression (15.29 ), or (3) the name of an enum constant (8.9.1 ); otherwise a compile-time error occurs. A|case|label that has a|null||case|constant may have an optional|default|. /For a case label with case patterns/, it is a compile-time error if any of its|case|patterns declares one or more pattern variables. I am not sure about the definition of dominance here.? If I have: ??? case Integer _, String _:? A; ??? case Number _ : B; Number dominates Integer, but it doesn't dominate Integer|String.? I think you mean "if at least one of pi..pn dominates *all* of the patterns ri..rm, no? But I'm not even sure if this is the right formulation, because: ??? sealed interface I permits A, B { } ??? record A() implements I {} ??? record B() implements I {} ??? case A _, B _: ... ??? case I i: ... The first case label dominates I.? So I think you have to appeal to exhaustiveness: "A case label with case patterns p1...pm dominates another case label with case patterns q1...qm if the set of patterns { p1..pm } dominates each qi", no? You probably have to slightly refactor the second statement about "compile time error if dominance" accordingly. On 1/26/2023 5:36 AM, Angelos Bimpoudis wrote: > Dear experts, > > The first draft of the JLS spec about unnamed patterns and variables > (https://openjdk.org/jeps/8294349) is available at: > > https://cr.openjdk.java.net/~abimpoudis/unnamed/latest/ > > Comments very much welcomed! > Angelos -------------- next part -------------- An HTML attachment was scrubbed... URL: From archie.cobbs at gmail.com Tue Jan 31 20:45:02 2023 From: archie.cobbs at gmail.com (Archie Cobbs) Date: Tue, 31 Jan 2023 14:45:02 -0600 Subject: JDK-8300786 - No longer require super() and this() to appear first in a constructor Message-ID: Hi folks, I'm working on this issue: JDK-8194743 - Permit additional statements before this/super in constructors. Obviously this change requires a JEP, and so we have this JEP draft for review: JDK-8300786 - No longer require super() and this() to appear first in a constructor Here's a summary of the discussion that's occurred so far on amber-dev... People are agreeable with the general idea of relaxing the JLS rules here, but of course the devil is in the details. The current JMVS gives constructors a lot more flexibility wrt. superclass initialization than the JLS: - Multiple invocations of this() and/or super() may appear in a constructor, as long as on any code path there is exactly one invocation - Arbitrary code may appear before this()/super(), as long as that code doesn't reference the instance under construction, with an exception carved out for field assignments - However, invocations of this()/super() may not appear within a try { } block (i.e., within a bytecode exception range) So the question becomes, how far to push the JLS up against these limits, or conceivably even past them (i.e., relaxing both the JLS and JVMS). Roughly in order of increasing aggressiveness, here are some of the options that have been discussed (these are not all mutually exclusive): 1. Permit "static context" code prior to super()/this(), but otherwise super()/this() still must occur exactly once and as a top-level statement in the constructor. 2. Allow arbitrary appearances of super()/this() in constructors, and apply DA/DU analysis like a blank final field to verify exactly one ever gets invoked 3. Also allow assignments to fields declared in the same class prior to super()/this() 4. (JVMS mod required) Allow super()/this() within try { } blocks, as long as within any catch block execution completes abruptly with another throw #1 is the minimal change. It accomplishes the basic goal of allowing "housekeeping" prior to superclass initialization. It also requires fairly minimal JLS changes (drafted already in the JEP). #2 is arguably a more natural way to relax things, but beyond #1 it addresses a fairly niche set of incremental use cases, and would have a large impact on the JLS for that relatively meager marginal return. #3 is debatable. The 'this' escape problem (e.g., HashSet(Collection)) is very real and Java provides victim subclasses with no easy way to avoid it. This feature would make it easy to avoid. However, it has a conceptual cost. Allowing field assignments, but no other 'this' references, is an obvious hack/exception to the rules. To be sure, there are practical reasons for it (which is why it was added to the JVMS in the first place), but from a language design point of view it left some people a little uneasy. It's a classic beauty vs. function debate. #4 is kind of a related side issue that came up. It could stand alone as an independent change. I'd be curious to hear people's opinions here. It would allow you to catch exceptions thrown by a super()/this() call as long as you then (re)throw some exception. It would also fix a difficulty for bytecode weaving tools that do things like measure method execution times. One could also argue that by making super()/this() calls more like normal method calls (less "special"), items #2 and #4 would improve language harmony, etc. In any case, the current JEP draft takes the conservative route and opts for #1 only. Thanks, -Archie -- Archie L. Cobbs -------------- next part -------------- An HTML attachment was scrubbed... URL: From amaembo at gmail.com Tue Jan 31 21:29:33 2023 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 31 Jan 2023 22:29:33 +0100 Subject: JDK-8300786 - No longer require super() and this() to appear first in a constructor In-Reply-To: References: Message-ID: Hello! >From an IDE guy point of view, I can say that #1 already greatly reduces our pain in automated refactorings and quick-fixes. Often, we need to insert additional statements before the refactored expression. Notable refactorings include "inline method call", "introduce local variable", "convert stream to loop". All of them are disabled in certain contexts like inside this/super invocation, as we cannot add statements before. It's even more pitiful, as sometimes refactoring is performed internally in several steps, and subsequent steps remove extra statements. E.g., "inline method" may add temporary variables for parameters or return values, and then optimize them away yielding a single expression as a result. So it would work inside this/super expression even in current Java, but due to internal architecture, we don't know in advance whether we'll need additional statements, so we refuse to refactor completely if the call is inside this/super. Things will be much simpler if additional statements were allowed. #2 would unlock some more refactorings, notably "Convert ?: to if-else", if ?: operator appears in this/super invocation. But in general, it adds much less benefit. I don't think that #3 over #2 adds anything useful for IDE functionality. #4 might allow to quick-fix compilation error (surround with try-catch) when a checked exception is thrown from this/super call arguments. Currently, we suggest such a fix but it produces another compilation error. In any case, this is probably a rare situation when you have such a case and really want to handle this exception right in the constructor, rather than rethrowing. To conclude, I would be quite happy with #1 already. With best regards, Tagir Valeev. On Tue, Jan 31, 2023 at 9:46 PM Archie Cobbs wrote: > > Hi folks, > > I'm working on this issue: > > JDK-8194743 - Permit additional statements before this/super in constructors. > > Obviously this change requires a JEP, and so we have this JEP draft for review: > > JDK-8300786 - No longer require super() and this() to appear first in a constructor > > Here's a summary of the discussion that's occurred so far on amber-dev... > > People are agreeable with the general idea of relaxing the JLS rules here, but of course the devil is in the details. > > The current JMVS gives constructors a lot more flexibility wrt. superclass initialization than the JLS: > > Multiple invocations of this() and/or super() may appear in a constructor, as long as on any code path there is exactly one invocation > Arbitrary code may appear before this()/super(), as long as that code doesn't reference the instance under construction, with an exception carved out for field assignments > However, invocations of this()/super() may not appear within a try { } block (i.e., within a bytecode exception range) > > So the question becomes, how far to push the JLS up against these limits, or conceivably even past them (i.e., relaxing both the JLS and JVMS). > > Roughly in order of increasing aggressiveness, here are some of the options that have been discussed (these are not all mutually exclusive): > > Permit "static context" code prior to super()/this(), but otherwise super()/this() still must occur exactly once and as a top-level statement in the constructor. > Allow arbitrary appearances of super()/this() in constructors, and apply DA/DU analysis like a blank final field to verify exactly one ever gets invoked > Also allow assignments to fields declared in the same class prior to super()/this() > (JVMS mod required) Allow super()/this() within try { } blocks, as long as within any catch block execution completes abruptly with another throw > > #1 is the minimal change. It accomplishes the basic goal of allowing "housekeeping" prior to superclass initialization. It also requires fairly minimal JLS changes (drafted already in the JEP). > > #2 is arguably a more natural way to relax things, but beyond #1 it addresses a fairly niche set of incremental use cases, and would have a large impact on the JLS for that relatively meager marginal return. > > #3 is debatable. The 'this' escape problem (e.g., HashSet(Collection)) is very real and Java provides victim subclasses with no easy way to avoid it. This feature would make it easy to avoid. However, it has a conceptual cost. Allowing field assignments, but no other 'this' references, is an obvious hack/exception to the rules. To be sure, there are practical reasons for it (which is why it was added to the JVMS in the first place), but from a language design point of view it left some people a little uneasy. It's a classic beauty vs. function debate. > > #4 is kind of a related side issue that came up. It could stand alone as an independent change. I'd be curious to hear people's opinions here. It would allow you to catch exceptions thrown by a super()/this() call as long as you then (re)throw some exception. It would also fix a difficulty for bytecode weaving tools that do things like measure method execution times. > > One could also argue that by making super()/this() calls more like normal method calls (less "special"), items #2 and #4 would improve language harmony, etc. > > In any case, the current JEP draft takes the conservative route and opts for #1 only. > > Thanks, > -Archie > > -- > Archie L. Cobbs