From forax at univ-mlv.fr Fri Sep 15 16:09:10 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 15 Sep 2023 18:09:10 +0200 (CEST) Subject: String Templates Expression Statement In-Reply-To: <35f63518-eb8d-6db1-8745-2ea80641c216@oracle.com> References: <35f63518-eb8d-6db1-8745-2ea80641c216@oracle.com> Message-ID: <1136052418.39573496.1694794149996.JavaMail.zimbra@univ-eiffel.fr> Given this is a spec issue, I think it should be discussed on the spec-experts list, > From: "Brian Goetz" > To: "Bas Leijdekkers" , "amber-dev" > > Sent: Friday, September 15, 2023 5:17:53 PM > Subject: Re: String Templates Expression Statement > We have gone back and forth on this, but I believe we are better served by not > allowing string templates as statement expressions. A string template is > supposed to _produce something_, not _operate by side effects_. A statement > expression serves only to normalize its use to produce side effects. A string template is a value, it does not produce anything. So I suppose you mean a String template "processor" is supposed to produce something. And for the record, the reason we are giong back and forth is that restricting the syntax to only support expression does not fit well with the fact that a processor is specified as an interface. So we are allowing the definition of a processor to have states but we are disallowing the syntax that calls a processor to modify those states. Personnally, I can leave with that, the Java semantics is full of this kind of special cases. And if someone really want a processor to acts as builder in the generic sense, the syntax var _ = processor."..."; works anyway. R?mi > On 7/12/2023 7:26 AM, Bas Leijdekkers wrote: >> Hello Amber-dev, >> In the String Templates draft specification, I don't see any changes in JLS >> Chapter 14.8 Expression Statements. This makes me think that Template >> Expressions are not allowed to be used as statements. However javac in jdk21-ea >> accepts a Template Expression used as a statement without reporting any error. >> (I am using build 21-ea+30-2426). So it appears to me either the specification >> or javac is incorrect. Which one should I believe? >> Example code: >> ``` >> class TemplateExpressionStatement { >> public static void main(String[] args) { >> STR."\{}"; >> } >> } >> ``` >> Bas -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Fri Sep 15 16:27:07 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 15 Sep 2023 18:27:07 +0200 (CEST) Subject: The String template API is about the processor, not the template Message-ID: <218655931.39580822.1694795227883.JavaMail.zimbra@univ-eiffel.fr> I know that I'm asking a lot, but I believe the way the String template JEP is written and the API is designed uses the wrong center. This spec is not about the string template, it's about the template processor, the string template is just a parameter of the processor. This was not true historically, StringTemplate was the design center. But when we required the syntax to be always prefixed by a template processor, we have make the template processor the new design center. Currently the API is designed with the processor interface defined as a member interface of StringTemplate. I think we should go the other way around, the top level construct should be the interface TemplateProcessor and StringTemplate should be defined as a member of TemplateProcessor. If you think about it, a lot of our users may use a TemplateProcessor but only few will either implement a template processor or use RAW, so knowning what a StringTemplate is a not something most of our users will have to learn. regards, R?mi From amaembo at gmail.com Tue Sep 26 12:32:06 2023 From: amaembo at gmail.com (Tagir Valeev) Date: Tue, 26 Sep 2023 14:32:06 +0200 Subject: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> Message-ID: Hello! As we are finalizing this feature, can we squeeze in a little improvement? Namely, support enum and patterns within the same case label, provided that the patterns do not declare any variables. Like: enum X {A, B} static void test(Object obj) { switch (obj) { case String _, X.B -> System.out.println("B or String"); default -> System.out.println("other"); } } public static void main(String[] args) { Test.test("ddd"); Test.test(X.B); } Currently, such a code is not supported. Or will it be considered in future JEPs? With best regards, Tagir Valeev. On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold wrote: > > https://openjdk.org/jeps/456 > > Summary: Enhance the Java language with unnamed variables, which > can be initialized but not used, and unnamed patterns, which match a > record component without stating the component's name or type. Both are > denoted by an underscore character, _. > > - Mark From forax at univ-mlv.fr Tue Sep 26 12:35:47 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 26 Sep 2023 14:35:47 +0200 (CEST) Subject: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> Message-ID: <1188570551.4510189.1695731747548.JavaMail.zimbra@univ-eiffel.fr> ----- Original Message ----- > From: "Tagir Valeev" > To: "amber-dev" > Cc: "Angelos Bimpoudis" , "amber-spec-experts" > Sent: Tuesday, September 26, 2023 2:32:06 PM > Subject: Re: New candidate JEP: 456: Unnamed Variables and Patterns > Hello! As we are finalizing this feature, can we squeeze in a little > improvement? Namely, support enum and patterns within the same case > label, provided that the patterns do not declare any variables. Like: > > enum X {A, B} > > static void test(Object obj) { > switch (obj) { > case String _, X.B -> System.out.println("B or String"); > default -> System.out.println("other"); > } > } > > public static void main(String[] args) { > Test.test("ddd"); > Test.test(X.B); > } > > Currently, such a code is not supported. Or will it be considered in > future JEPs? This is a nice improvement. > > With best regards, > Tagir Valeev. regards, R?mi > > On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold wrote: >> >> https://openjdk.org/jeps/456 >> >> Summary: Enhance the Java language with unnamed variables, which >> can be initialized but not used, and unnamed patterns, which match a >> record component without stating the component's name or type. Both are >> denoted by an underscore character, _. >> > > - Mark From brian.goetz at oracle.com Tue Sep 26 13:16:20 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 26 Sep 2023 09:16:20 -0400 Subject: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> Message-ID: I am pretty sure I saw some spec language for this go by, but Gavin can fill in the details.? But yes, this is desirable because it should be possible to mix enums and records under a sealed type: ??? sealed interface X { } ??? enum E implements X { A; } ??? record R(int x) implements X { } ??? ... ??? switch (x) { ??????? case E.A: ... ??????? case R(int x): ... ??????? // exhaustive! ??? } There is some spec trickiness because switches on enum selectors _must_ use unqualified names historically, and this has to be rationalized. On 9/26/2023 8:32 AM, Tagir Valeev wrote: > Hello! As we are finalizing this feature, can we squeeze in a little > improvement? Namely, support enum and patterns within the same case > label, provided that the patterns do not declare any variables. Like: > > enum X {A, B} > > static void test(Object obj) { > switch (obj) { > case String _, X.B -> System.out.println("B or String"); > default -> System.out.println("other"); > } > } > > public static void main(String[] args) { > Test.test("ddd"); > Test.test(X.B); > } > > Currently, such a code is not supported. Or will it be considered in > future JEPs? > > With best regards, > Tagir Valeev. > > On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold wrote: >> https://openjdk.org/jeps/456 >> >> Summary: Enhance the Java language with unnamed variables, which >> can be initialized but not used, and unnamed patterns, which match a >> record component without stating the component's name or type. Both are >> denoted by an underscore character, _. >> >> - Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Tue Sep 26 13:52:47 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Tue, 26 Sep 2023 09:52:47 -0400 Subject: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> Message-ID: <2822e0e8-796f-168d-4866-21b40247069b@oracle.com> I see now I answered a slightly different question :) We do support case labels for enums in pattern switches, and they participate in exhaustiveness.? But we don't currently support mixing `case pattern, constant-label` in a single case label.? This is waiting for a more comprehensive treatment of constants as patterns. On 9/26/2023 8:32 AM, Tagir Valeev wrote: > Hello! As we are finalizing this feature, can we squeeze in a little > improvement? Namely, support enum and patterns within the same case > label, provided that the patterns do not declare any variables. Like: > > enum X {A, B} > > static void test(Object obj) { > switch (obj) { > case String _, X.B -> System.out.println("B or String"); > default -> System.out.println("other"); > } > } > > public static void main(String[] args) { > Test.test("ddd"); > Test.test(X.B); > } > > Currently, such a code is not supported. Or will it be considered in > future JEPs? > > With best regards, > Tagir Valeev. > > On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold wrote: >> https://openjdk.org/jeps/456 >> >> Summary: Enhance the Java language with unnamed variables, which >> can be initialized but not used, and unnamed patterns, which match a >> record component without stating the component's name or type. Both are >> denoted by an underscore character, _. >> >> - Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: From gavin.bierman at oracle.com Tue Sep 26 16:14:23 2023 From: gavin.bierman at oracle.com (Gavin Bierman) Date: Tue, 26 Sep 2023 16:14:23 +0000 Subject: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: <2822e0e8-796f-168d-4866-21b40247069b@oracle.com> References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> <2822e0e8-796f-168d-4866-21b40247069b@oracle.com> Message-ID: <50EB1B68-D36E-439E-A8B3-7715744D247D@oracle.com> That?s right. We made a decision to simplify the grammar of switch labels for the JEP to only have a single pattern. However, if you use the "colon form? you can express similar code: gmb at gmb-mac src % cat Switch.java public class Switch { sealed interface X { } enum E implements X {A;} record R() implements X { } public void work(X x) { var result = switch (x) { case E.A: case R(): yield 42; // exhaustive! }; } public static void main(String[] args) { System.out.println("complete"); } } gmb at gmb-mac src % java Switch.java complete As you point out, a more uniform treatment would treat all constants as patterns and allow them all to appear in pattern lists of record patterns, for example. Working on it!! Gavin On 26 Sep 2023, at 14:52, Brian Goetz wrote: I see now I answered a slightly different question :) We do support case labels for enums in pattern switches, and they participate in exhaustiveness. But we don't currently support mixing `case pattern, constant-label` in a single case label. This is waiting for a more comprehensive treatment of constants as patterns. On 9/26/2023 8:32 AM, Tagir Valeev wrote: Hello! As we are finalizing this feature, can we squeeze in a little improvement? Namely, support enum and patterns within the same case label, provided that the patterns do not declare any variables. Like: enum X {A, B} static void test(Object obj) { switch (obj) { case String _, X.B -> System.out.println("B or String"); default -> System.out.println("other"); } } public static void main(String[] args) { Test.test("ddd"); Test.test(X.B); } Currently, such a code is not supported. Or will it be considered in future JEPs? With best regards, Tagir Valeev. On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold wrote: https://openjdk.org/jeps/456 Summary: Enhance the Java language with unnamed variables, which can be initialized but not used, and unnamed patterns, which match a record component without stating the component's name or type. Both are denoted by an underscore character, _. - Mark -------------- next part -------------- An HTML attachment was scrubbed... URL: From angelos.bimpoudis at oracle.com Wed Sep 27 13:33:26 2023 From: angelos.bimpoudis at oracle.com (Angelos Bimpoudis) Date: Wed, 27 Sep 2023 13:33:26 +0000 Subject: [External] : Re: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> <2822e0e8-796f-168d-4866-21b40247069b@oracle.com> <50EB1B68-D36E-439E-A8B3-7715744D247D@oracle.com> Message-ID: Hello Clement! Thanks for letting us know. I recreated a stand alone reproduction of your report and indeed I get the verification error: https://bugs.openjdk.org/browse/JDK-8317048 Looking into it. Angelos ________________________________ From: Cl?ment BOUDEREAU Sent: 27 September 2023 09:55 To: Gavin Bierman Cc: Brian Goetz ; Tagir Valeev ; amber-dev at openjdk.org ; Angelos Bimpoudis ; amber-spec-experts Subject: [External] : Re: New candidate JEP: 456: Unnamed Variables and Patterns Hi Amber dev team, Firstly, thank you for the awesome work done. I tried to use unnamed variable to simplifiy pattern matching in existing code with preview feature enable and JDK21 but ended up with runtime exception. The code compiles but unit test fails while I am actually running unit test with other preview feature. Here is the PR with the problem and temporary workaround : https://github.com/cboudereau/dataseries/pull/34 FYI, I have another pull request to integrate as soon as possible preview feature of the latest jdk21 here where everything work fine locally : https://github.com/cboudereau/dataseries/pull/24 Here is the error at runtime: [ERROR] SimpleTest.simple:17 ?? Verify Bad local variable type Exception Details: Location: io/github/cboudereau/dataseries/Union$Value.compareTo(Lio/github/cboudereau/dataseries/Union$Value;)I @297: aload Reason: Type top (current frame, locals[9]) is not assignable to reference type Current Frame: bci: @297 flags: { } locals: { 'io/github/cboudereau/dataseries/Union$Value', 'io/github/cboudereau/dataseries/Union$Value', '[Z', 'io/github/cboudereau/dataseries/Union$Value$Tuple', integer, 'io/github/cboudereau/dataseries/Union$Value$Tuple', top, top, top, top, top, 'io/github/cboudereau/dataseries/Union$Value$Fixed', 'io/github/cboudereau/dataseries/Union$Value', integer, 'io/github/cboudereau/dataseries/Union$Value', integer } stack: { } Bytecode: 0000000: 1278 c000 7a4d bb00 0c59 2a2b b700 0e59 0000010: b800 1157 4e03 3604 2c05 0454 2d15 04ba 0000020: 0017 0000 ab00 0000 0000 0014 0000 0001 0000030: 0000 0000 0000 0022 bb00 1b59 0101 b700 0000040: 1d2c 0604 54bf 2d3a 0519 052c 0704 54b6 0000050: 0020 c000 243a 0c2c 0804 5403 360d 2c10 0000060: 0604 5419 0c15 0dba 0026 0000 aa00 0000 0000070: 0000 00df ffff ffff 0000 0001 0000 00df 0000080: 0000 001c 0000 006d 1905 2c10 0704 54b6 0000090: 0027 c000 243a 0e03 360f 190e 150f ba00 00000a0: 2600 00aa 0000 002b ffff ffff 0000 0001 00000b0: 0000 002b 0000 0019 0000 0022 032c 1008 00000c0: 0454 a700 9404 2c10 0904 54a7 008b 0436 00000d0: 0d2c 100a 0454 a7ff 8d19 052c 100b 0454 00000e0: b600 27c0 0024 3a0e 2c10 0c04 5403 360f 00000f0: 190e 150f ba00 2600 00aa 0000 0000 0047 0000100: ffff ffff 0000 0001 0000 0047 0000 001b 0000110: 0000 0024 022c 100d 0454 a700 3c19 0ec0 0000120: 0001 3a0b 2c10 0e04 5419 09b4 002a 190b 0000130: b400 2ab9 002e 0200 2c10 0f04 54a7 0019 0000140: 0536 0d2c 1010 0454 a7ff 1b04 3604 2c10 0000150: 1104 54a7 fec9 2c10 1204 54ac 4ebb 001b 0000160: 592d b600 362d b700 1d2c 1013 0454 bf Exception Handler Table: bci [75, 82] => handler: 348 bci [138, 146] => handler: 348 bci [219, 227] => handler: 348 Stackmap Table: append_frame(@28,Object[#122],Object[#12],Integer) same_frame(@56) same_frame(@70) full_frame(@99,{Object[#36],Object[#36],Object[#122],Object[#12],Integer,Object[#12],Top,Top,Top,Top,Top,Top,Object[#36],Integer},{}) same_frame(@136) append_frame(@154,Object[#36],Integer) same_frame(@188) same_frame(@197) same_frame(@206) chop_frame(@217,2) append_frame(@240,Object[#36],Integer) same_frame(@276) same_frame(@285) same_frame(@320) chop_frame(@331,2) full_frame(@342,{Object[#36],Object[#36],Object[#122]},{Integer}) same_locals_1_stack_item_frame(@348,Object[#52]) On Tue, Sep 26, 2023 at 6:14?PM Gavin Bierman > wrote: That?s right. We made a decision to simplify the grammar of switch labels for the JEP to only have a single pattern. However, if you use the "colon form? you can express similar code: gmb at gmb-mac src % cat Switch.java public class Switch { sealed interface X { } enum E implements X {A;} record R() implements X { } public void work(X x) { var result = switch (x) { case E.A: case R(): yield 42; // exhaustive! }; } public static void main(String[] args) { System.out.println("complete"); } } gmb at gmb-mac src % java Switch.java complete As you point out, a more uniform treatment would treat all constants as patterns and allow them all to appear in pattern lists of record patterns, for example. Working on it!! Gavin On 26 Sep 2023, at 14:52, Brian Goetz > wrote: I see now I answered a slightly different question :) We do support case labels for enums in pattern switches, and they participate in exhaustiveness. But we don't currently support mixing `case pattern, constant-label` in a single case label. This is waiting for a more comprehensive treatment of constants as patterns. On 9/26/2023 8:32 AM, Tagir Valeev wrote: Hello! As we are finalizing this feature, can we squeeze in a little improvement? Namely, support enum and patterns within the same case label, provided that the patterns do not declare any variables. Like: enum X {A, B} static void test(Object obj) { switch (obj) { case String _, X.B -> System.out.println("B or String"); default -> System.out.println("other"); } } public static void main(String[] args) { Test.test("ddd"); Test.test(X.B); } Currently, such a code is not supported. Or will it be considered in future JEPs? With best regards, Tagir Valeev. On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold wrote: https://openjdk.org/jeps/456 Summary: Enhance the Java language with unnamed variables, which can be initialized but not used, and unnamed patterns, which match a record component without stating the component's name or type. Both are denoted by an underscore character, _. - Mark -- C.BOUDEREAU -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Wed Sep 27 13:59:35 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 27 Sep 2023 15:59:35 +0200 (CEST) Subject: [External] : Re: New candidate JEP: 456: Unnamed Variables and Patterns In-Reply-To: References: <20230925144015.B4B3C6491DB@eggemoggin.niobe.net> <2822e0e8-796f-168d-4866-21b40247069b@oracle.com> <50EB1B68-D36E-439E-A8B3-7715744D247D@oracle.com> Message-ID: <1947390671.6046878.1695823175328.JavaMail.zimbra@univ-eiffel.fr> > From: "Angelos Bimpoudis" > To: "Cl?ment BOUDEREAU" , "Gavin Bierman" > > Cc: "Brian Goetz" , "Tagir Valeev" , > "amber-dev" , "amber-spec-experts" > > Sent: Wednesday, September 27, 2023 3:33:26 PM > Subject: Re: [External] : Re: New candidate JEP: 456: Unnamed Variables and > Patterns > Hello Clement! > Thanks for letting us know. I recreated a stand alone reproduction of your > report and indeed I get the verification error: [ > https://bugs.openjdk.org/browse/JDK-8317048 | > https://bugs.openjdk.org/browse/JDK-8317048 ] > Looking into it. > Angelos Hello Angelos, you can also log another bug, it seems that javac allows "final" in front of a record pattern, something which is not allowed by the grammar (and also rightfully rejected by IntelliJ). record Foo ( int x) {} public static void main ( String [] args ) { Object o = args ; switch ( o ) { case final Foo( int x) -> {} // oops ! default -> {} } } regards, R?mi > From: Cl?ment BOUDEREAU > Sent: 27 September 2023 09:55 > To: Gavin Bierman > Cc: Brian Goetz ; Tagir Valeev ; > amber-dev at openjdk.org ; Angelos Bimpoudis > ; amber-spec-experts > > Subject: [External] : Re: New candidate JEP: 456: Unnamed Variables and Patterns > Hi Amber dev team, > Firstly, thank you for the awesome work done. > I tried to use unnamed variable to simplifiy pattern matching in existing code > with preview feature enable and JDK21 but ended up with runtime exception. The > code compiles but unit test fails while I am actually running unit test with > other preview feature. > Here is the PR with the problem and temporary workaround : > [ > https://urldefense.com/v3/__https://github.com/cboudereau/dataseries/pull/34__;!!ACWV5N9M2RV99hQ!IQaUoSdPFw6-k9Xl8bh66a2ULWyr2pCGqHgDBldDFjJNesjswhMSNWPshaJor8k95x4FVDPHBA2WQlMKyak3HQUSGQ$ > | https://github.com/cboudereau/dataseries/pull/34 ] > FYI, I have another pull request to integrate as soon as possible preview > feature of the latest jdk21 here where everything work fine locally : > [ > https://urldefense.com/v3/__https://github.com/cboudereau/dataseries/pull/24__;!!ACWV5N9M2RV99hQ!IQaUoSdPFw6-k9Xl8bh66a2ULWyr2pCGqHgDBldDFjJNesjswhMSNWPshaJor8k95x4FVDPHBA2WQlMKyakzNtsm5g$ > | https://github.com/cboudereau/dataseries/pull/24 ] > Here is the error at runtime: > [ERROR] SimpleTest.simple:17 ?? Verify Bad local variable type > Exception Details: > Location: > io/github/cboudereau/dataseries/Union$Value.compareTo(Lio/github/cboudereau/dataseries/Union$Value;)I > @297: aload > Reason: > Type top (current frame, locals[9]) is not assignable to reference type > Current Frame: > bci: @297 > flags: { } > locals: { 'io/github/cboudereau/dataseries/Union$Value', > 'io/github/cboudereau/dataseries/Union$Value', '[Z', > 'io/github/cboudereau/dataseries/Union$Value$Tuple', integer, > 'io/github/cboudereau/dataseries/Union$Value$Tuple', top, top, top, top, top, > 'io/github/cboudereau/dataseries/Union$Value$Fixed', > 'io/github/cboudereau/dataseries/Union$Value', integer, > 'io/github/cboudereau/dataseries/Union$Value', integer } > stack: { } > Bytecode: > 0000000: 1278 c000 7a4d bb00 0c59 2a2b b700 0e59 > 0000010: b800 1157 4e03 3604 2c05 0454 2d15 04ba > 0000020: 0017 0000 ab00 0000 0000 0014 0000 0001 > 0000030: 0000 0000 0000 0022 bb00 1b59 0101 b700 > 0000040: 1d2c 0604 54bf 2d3a 0519 052c 0704 54b6 > 0000050: 0020 c000 243a 0c2c 0804 5403 360d 2c10 > 0000060: 0604 5419 0c15 0dba 0026 0000 aa00 0000 > 0000070: 0000 00df ffff ffff 0000 0001 0000 00df > 0000080: 0000 001c 0000 006d 1905 2c10 0704 54b6 > 0000090: 0027 c000 243a 0e03 360f 190e 150f ba00 > 00000a0: 2600 00aa 0000 002b ffff ffff 0000 0001 > 00000b0: 0000 002b 0000 0019 0000 0022 032c 1008 > 00000c0: 0454 a700 9404 2c10 0904 54a7 008b 0436 > 00000d0: 0d2c 100a 0454 a7ff 8d19 052c 100b 0454 > 00000e0: b600 27c0 0024 3a0e 2c10 0c04 5403 360f > 00000f0: 190e 150f ba00 2600 00aa 0000 0000 0047 > 0000100: ffff ffff 0000 0001 0000 0047 0000 001b > 0000110: 0000 0024 022c 100d 0454 a700 3c19 0ec0 > 0000120: 0001 3a0b 2c10 0e04 5419 09b4 002a 190b > 0000130: b400 2ab9 002e 0200 2c10 0f04 54a7 0019 > 0000140: 0536 0d2c 1010 0454 a7ff 1b04 3604 2c10 > 0000150: 1104 54a7 fec9 2c10 1204 54ac 4ebb 001b > 0000160: 592d b600 362d b700 1d2c 1013 0454 bf > Exception Handler Table: > bci [75, 82] => handler: 348 > bci [138, 146] => handler: 348 > bci [219, 227] => handler: 348 > Stackmap Table: > append_frame(@28,Object[#122],Object[#12],Integer) > same_frame(@56) > same_frame(@70) > full_frame(@99,{Object[#36],Object[#36],Object[#122],Object[#12],Integer,Object[#12],Top,Top,Top,Top,Top,Top,Object[#36],Integer},{}) > same_frame(@136) > append_frame(@154,Object[#36],Integer) > same_frame(@188) > same_frame(@197) > same_frame(@206) > chop_frame(@217,2) > append_frame(@240,Object[#36],Integer) > same_frame(@276) > same_frame(@285) > same_frame(@320) > chop_frame(@331,2) > full_frame(@342,{Object[#36],Object[#36],Object[#122]},{Integer}) > same_locals_1_stack_item_frame(@348,Object[#52]) > On Tue, Sep 26, 2023 at 6:14 PM Gavin Bierman < [ > mailto:gavin.bierman at oracle.com | gavin.bierman at oracle.com ] > wrote: >> That?s right. We made a decision to simplify the grammar of switch labels for >> the JEP to only have a single pattern. However, if you use the "colon form? you >> can express similar code: >> gmb at gmb-mac src % cat Switch.java >> public class Switch { >> sealed interface X { } >> enum E implements X {A;} >> record R() implements X { } >> public void work(X x) { >> var result = switch (x) { >> case E.A: >> case R(): yield 42; >> // exhaustive! >> }; >> } >> public static void main(String[] args) { >> System.out.println("complete"); >> } >> } >> gmb at gmb-mac src % java Switch.java >> complete >> As you point out, a more uniform treatment would treat all constants as patterns >> and allow them all to appear in pattern lists of record patterns, for example. >> Working on it!! >> Gavin >>> On 26 Sep 2023, at 14:52, Brian Goetz < [ mailto:brian.goetz at oracle.com | >>> brian.goetz at oracle.com ] > wrote: >>> I see now I answered a slightly different question :) >>> We do support case labels for enums in pattern switches, and they participate in >>> exhaustiveness. But we don't currently support mixing `case pattern, >>> constant-label` in a single case label. This is waiting for a more >>> comprehensive treatment of constants as patterns. >>> On 9/26/2023 8:32 AM, Tagir Valeev wrote: >>>> Hello! As we are finalizing this feature, can we squeeze in a little >>>> improvement? Namely, support enum and patterns within the same case >>>> label, provided that the patterns do not declare any variables. Like: >>>> enum X {A, B} >>>> static void test(Object obj) { >>>> switch (obj) { >>>> case String _, X.B -> System.out.println("B or String"); >>>> default -> System.out.println("other"); >>>> } >>>> } >>>> public static void main(String[] args) { >>>> Test.test("ddd"); >>>> Test.test(X.B); >>>> } >>>> Currently, such a code is not supported. Or will it be considered in >>>> future JEPs? >>>> With best regards, >>>> Tagir Valeev. >>>> On Mon, Sep 25, 2023 at 6:25?PM Mark Reinhold [ mailto:mark.reinhold at oracle.com >>>> | ] wrote: >>>>> [ https://openjdk.org/jeps/456 | https://openjdk.org/jeps/456 ] Summary: Enhance >>>>> the Java language with unnamed variables, which >>>>> can be initialized but not used, and unnamed patterns, which match a >>>>> record component without stating the component's name or type. Both are >>>>> denoted by an underscore character, _. >>>>> - Mark > -- > C.BOUDEREAU -------------- next part -------------- An HTML attachment was scrubbed... URL: From forax at univ-mlv.fr Wed Sep 27 14:03:18 2023 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 27 Sep 2023 16:03:18 +0200 (CEST) Subject: Switch on several values Message-ID: <525180955.6049957.1695823398327.JavaMail.zimbra@univ-eiffel.fr> Hi recently Cl?ment BOUDEREAU has reported a bug on amber-dev and unrelated to that bug, taking a look to the code I've noticed this int compareTo(final Value o) { return switch (new Tuple<>(this, o)) { case Tuple, Value>(Value.Infinite _, Value.Infinite _) -> 0; case Tuple, Value>(Value.Infinite _, Value.Fixed _) -> 1; case Tuple, Value>(Value.Fixed _, Value.Infinite _) -> -1; case Tuple, Value>(Value.Fixed fst, Value.Fixed snd) -> fst.value.compareTo(snd.value); }; } Here what Cl?ment want is to match two values (here, "this" and "o") but the only way to do that is to wrap them into a pair (here named Tuple), Should we not provide a way to match several values natively ? Something like int compareTo(final Value o) { return switch (this, o) { case (Value.Infinite _, Value.Infinite _) -> 0; case (Value.Infinite _, Value.Fixed _) -> 1; case (Value.Fixed _, Value.Infinite _) -> -1; case (Value.Fixed fst, Value.Fixed snd) -> fst.value.compareTo(snd.value); }; } regards, R?mi From brian.goetz at oracle.com Wed Sep 27 14:18:25 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 27 Sep 2023 10:18:25 -0400 Subject: Switch on several values In-Reply-To: <525180955.6049957.1695823398327.JavaMail.zimbra@univ-eiffel.fr> References: <525180955.6049957.1695823398327.JavaMail.zimbra@univ-eiffel.fr> Message-ID: [ dropping amber-dev ] Yes, we've discussed this before.? A switch could have multiple selector values: ??? switch (a, b) and cases could be structured similarly: ??? case (P, Q): All of this isn't hard.? The real question is, does it result in better or worse code?? My sense is that it look really pretty in the simple examples, but as the number of selectors and the size of the patterns increases, it is likely to become an unreadable soup.? So that's a concern. As an example of a "the simple cases are very pretty", I give you a world-class FizzBuzz: ??? Function fizzbuzz = ??????? x -> switch (x % 3, x % 5) { ?? ? ? ?? ?????? case (0, 0) -> "FizzBuzz"; ?? ? ? ? ? ?? ?? case (0, _) -> "Fizz"; ? ? ? ????? ? ?? case (_, 0) -> "Buzz"; ? ?? ? ? ? ?? ?? default -> Integer.toString(x); ???????????? }; (I might have gotten my Fizz and Buzz backwards, I didn't bother to look it up.) I see the appeal in "Java is the #1 language for writing FizzBuzz", but I am not sure this is the stewardship rubric we are looking for :) Another problem (and this one is of our own making) is that comma already means something in cases.? So ??? case 0, 1 means something subtly different from ??? case (0, 1) which is not particularly nice.? Yes, the type checker will disambiguate for you, but we are not used to both `X` and `(X)` being valid in the same context but meaning different things. (Worse, when you combine these where you have multiple tuple patterns on one case, it's even more case soup.) So I put this one in the category of "simple enough to specify and implement, has obvious motivating use cases, but not sure it actually improves the language." On 9/27/2023 10:03 AM, Remi Forax wrote: > Hi recently Cl?ment BOUDEREAU has reported a bug on amber-dev and unrelated to that bug, > taking a look to the code I've noticed this > > > int compareTo(final Value o) { > return switch (new Tuple<>(this, o)) { > case Tuple, Value>(Value.Infinite _, Value.Infinite _) -> 0; > case Tuple, Value>(Value.Infinite _, Value.Fixed _) -> 1; > case Tuple, Value>(Value.Fixed _, Value.Infinite _) -> -1; > case Tuple, Value>(Value.Fixed fst, Value.Fixed snd) -> > fst.value.compareTo(snd.value); > }; > } > > Here what Cl?ment want is to match two values (here, "this" and "o") but the only way to do that is to wrap them into a pair (here named Tuple), > Should we not provide a way to match several values natively ? > > Something like > > int compareTo(final Value o) { > return switch (this, o) { > case (Value.Infinite _, Value.Infinite _) -> 0; > case (Value.Infinite _, Value.Fixed _) -> 1; > case (Value.Fixed _, Value.Infinite _) -> -1; > case (Value.Fixed fst, Value.Fixed snd) -> > fst.value.compareTo(snd.value); > }; > } > > regards, > R?mi -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed Sep 27 14:46:04 2023 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 27 Sep 2023 10:46:04 -0400 Subject: Switch on several values In-Reply-To: References: <525180955.6049957.1695823398327.JavaMail.zimbra@univ-eiffel.fr> Message-ID: Note too that we also considered the case (heh) of a switch with _zero_ selectors, as a replacement for chains of if-else that all produce a value to be consumed in a uniform way: ??? String s = switch { ??????? case when e1 -> x; ??????? case when e2 -> y; ??????? default -> z; ??? } This obviously doesn't have the problems I outlined with multi-selector, but it is definitely "weirder".? It seeks to capitalize on the strength reduction of switch relative to an if-else chain, but I'm also not convinced this one carries its weight. On 9/27/2023 10:18 AM, Brian Goetz wrote: > [ dropping amber-dev ] > > Yes, we've discussed this before.? A switch could have multiple > selector values: > > ??? switch (a, b) > > and cases could be structured similarly: > > ??? case (P, Q): > > All of this isn't hard.? The real question is, does it result in > better or worse code?? My sense is that it look really pretty in the > simple examples, but as the number of selectors and the size of the > patterns increases, it is likely to become an unreadable soup.? So > that's a concern. > > As an example of a "the simple cases are very pretty", I give you a > world-class FizzBuzz: > > ??? Function fizzbuzz = > ??????? x -> switch (x % 3, x % 5) { > ?? ? ? ?? ?????? case (0, 0) -> "FizzBuzz"; > ?? ? ? ? ? ?? ?? case (0, _) -> "Fizz"; > ? ? ? ????? ? ?? case (_, 0) -> "Buzz"; > ? ?? ? ? ? ?? ?? default -> Integer.toString(x); > ???????????? }; > > (I might have gotten my Fizz and Buzz backwards, I didn't bother to > look it up.) > > > I see the appeal in "Java is the #1 language for writing FizzBuzz", > but I am not sure this is the stewardship rubric we are looking for :) > > > Another problem (and this one is of our own making) is that comma > already means something in cases.? So > > ??? case 0, 1 > > means something subtly different from > > ??? case (0, 1) > > which is not particularly nice.? Yes, the type checker will > disambiguate for you, but we are not used to both `X` and `(X)` being > valid in the same context but meaning different things.? (Worse, when > you combine these where you have multiple tuple patterns on one case, > it's even more case soup.) > > So I put this one in the category of "simple enough to specify and > implement, has obvious motivating use cases, but not sure it actually > improves the language." > > > > On 9/27/2023 10:03 AM, Remi Forax wrote: >> Hi recently Cl?ment BOUDEREAU has reported a bug on amber-dev and unrelated to that bug, >> taking a look to the code I've noticed this >> >> >> int compareTo(final Value o) { >> return switch (new Tuple<>(this, o)) { >> case Tuple, Value>(Value.Infinite _, Value.Infinite _) -> 0; >> case Tuple, Value>(Value.Infinite _, Value.Fixed _) -> 1; >> case Tuple, Value>(Value.Fixed _, Value.Infinite _) -> -1; >> case Tuple, Value>(Value.Fixed fst, Value.Fixed snd) -> >> fst.value.compareTo(snd.value); >> }; >> } >> >> Here what Cl?ment want is to match two values (here, "this" and "o") but the only way to do that is to wrap them into a pair (here named Tuple), >> Should we not provide a way to match several values natively ? >> >> Something like >> >> int compareTo(final Value o) { >> return switch (this, o) { >> case (Value.Infinite _, Value.Infinite _) -> 0; >> case (Value.Infinite _, Value.Fixed _) -> 1; >> case (Value.Fixed _, Value.Infinite _) -> -1; >> case (Value.Fixed fst, Value.Fixed snd) -> >> fst.value.compareTo(snd.value); >> }; >> } >> >> regards, >> R?mi > -------------- next part -------------- An HTML attachment was scrubbed... URL: From amaembo at gmail.com Wed Sep 27 15:00:52 2023 From: amaembo at gmail.com (Tagir Valeev) Date: Wed, 27 Sep 2023 17:00:52 +0200 Subject: Switch on several values In-Reply-To: References: <525180955.6049957.1695823398327.JavaMail.zimbra@univ-eiffel.fr> Message-ID: On Wed, Sep 27, 2023 at 4:18?PM Brian Goetz wrote: > As an example of a "the simple cases are very pretty", I give you a world-class FizzBuzz: > > Function fizzbuzz = > x -> switch (x % 3, x % 5) { > case (0, 0) -> "FizzBuzz"; > case (0, _) -> "Fizz"; > case (_, 0) -> "Buzz"; > default -> Integer.toString(x); > }; This is basically a syntactic sugar for an unnamed tuple. I think, Java is not going to the unnamed tuples direction, as we have named ones (records). So it should be enough. We just need constant patterns: record Rems(int by3, int by5) {} Function fizzbuzz = x -> switch (new Rems(x % 3, x % 5)) { case Rems(0, 0) -> "FizzBuzz"; case Rems(0, _) -> "Fizz"; case Rems(_, 0) -> "Buzz"; default -> Integer.toString(x); }; In future, with custom matchers, we'll be able to do it even better. With best regards, Tagir Valeev.