> From: "Brian Goetz" <brian.go...@oracle.com> > To: "Remi Forax" <fo...@univ-mlv.fr>, "Tagir Valeev" <amae...@gmail.com> > Cc: "amber-spec-experts" <amber-spec-experts@openjdk.java.net> > Sent: Jeudi 28 Octobre 2021 19:48:40 > Subject: Re: switch expression with not explicit yield value should work ?
> If all branches throw, then you can refactor > switch (x) { > case X -> throw e; > ... > } > to > throw switch (x) { > case X -> e; > } now i feel i've been tricked by a Jedi :) Rémi > On 10/28/2021 1:12 PM, [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] wrote: >> I fell in the same trap yet again :( >> Am i the only one that want to throw exceptions in all branches of a switch >> ? [ >> https://github.com/forax/write_your_own_java_framework/blob/master/interceptor/src/test/java/org/github/forax/framework/interceptor/InterceptorRegistryTest.java#L523 >> | >> https://github.com/forax/write_your_own_java_framework/blob/master/interceptor/src/test/java/org/github/forax/framework/interceptor/InterceptorRegistryTest.java#L523 >> ] Rémi >> ----- Original Message ----- >>> From: "Tagir Valeev" [ mailto:amae...@gmail.com | <amae...@gmail.com> ] To: >>> "Remi Forax" [ mailto:fo...@univ-mlv.fr | <fo...@univ-mlv.fr> ] Cc: >>> "amber-spec-experts" [ mailto:amber-spec-experts@openjdk.java.net | >>> <amber-spec-experts@openjdk.java.net> ] Sent: Lundi 30 Août 2021 04:00:27 >>> Subject: Re: switch expression with not explicit yield value should work ? >>> Hello! >>> I think this is not related to recent JEPs. This behavior is >>> standardised since Java 14 when Switch expression was introduced: >>> // Compilation error >>> int x = switch(0) { >>> default -> throw new IllegalArgumentException(); >>> }; >>> This is explicitly specified (15.28.1) [1]: >>>> It is a compile-time error if a switch expression has no result >>>> expressions. >>> There was some discussion about this rule in March, 2019 [2]. >>> Basically, the idea is to preserve the possibility of normal >>> (non-abrupt) execution of every expression. >>> I believe, preventing unreachable code has always been in the spirit >>> of Java. In your code sample, the execution of the 'return' statement >>> itself is unreachable, >>> so writing 'return' is redundant. In my sample above, the 'x' variable >>> is never assigned to anything, and the subsequent statements (if any) >>> are unreachable as well. >>> I'd vote to keep the current behavior. While it may complicate code >>> generation and automatic refactorings, this additional complexity is >>> only marginal. The benefit is >>> that this behavior may save us from accidental mistakes. >>> Btw, you may deceive the compiler introducing a method like >>> static Object fail() { >>> throw new IllegalArgumentException(); >>> } >>> And use "case Object __ -> fail()" >>> With best regards, >>> Tagir Valeev. >>> [1] [ >>> https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.28.1 >>> | >>> https://docs.oracle.com/javase/specs/jls/se16/html/jls-15.html#jls-15.28.1 ] >>> [2] [ >>> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-March/001067.html >>> | >>> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-March/001067.html >>> ] On Sun, Aug 29, 2021 at 9:00 PM Remi Forax [ mailto:fo...@univ-mlv.fr | >>> <fo...@univ-mlv.fr> ] wrote: >>>> Another case where the spec is weird, >>>> i've converted a project that generate a visitor from a grammar (something >>>> like >>>> yacc) to use a switch on type instead. >>>> Sometimes for a degenerate portion of the grammar i've an empty visitor >>>> that >>>> always throw an exception, >>>> the equivalent code with a switch is >>>> static Object result(Object o) { >>>> return switch (o) { >>>> case Object __ -> throw new AssertionError(); >>>> }; >>>> } >>>> Obviously i can tweak the code generator to generate >>>> static Object result(Object o) { >>>> throw new AssertionError(); >>>> } >>>> but not be able to compile the former code strike me as odd. >>>> An expression switch is a poly-expression, so the result type is >>>> back-propagated >>>> from the return type of the method result, so it should be Object. >>>> Moreover, if the switch is not a switch expression but a switch statement, >>>> the >>>> code is also valid >>>> static Object result(Object o) { >>>> switch (o) { >>>> case Object __ -> throw new AssertionError(); >>>> } >>>> } >>>> Not be able to compile a switch expression when there is no explicit >>>> result type >>>> but only an implicit type seems arbitrary to me >>>> (this change is backward compatible because it only makes more codes >>>> compiling). >>>> Rémi