switch expression with not explicit yield value should work ?

forax at univ-mlv.fr forax at univ-mlv.fr
Thu Oct 28 18:04:53 UTC 2021


> From: "Brian Goetz" <brian.goetz at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>, "Tagir Valeev" <amaembo at gmail.com>
> Cc: "amber-spec-experts" <amber-spec-experts at 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:forax at univ-mlv.fr | forax at 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:amaembo at gmail.com | <amaembo at gmail.com> ] To:
>>> "Remi Forax" [ mailto:forax at univ-mlv.fr | <forax at univ-mlv.fr> ] Cc:
>>> "amber-spec-experts" [ mailto:amber-spec-experts at openjdk.java.net |
>>> <amber-spec-experts at 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:forax at univ-mlv.fr |
>>> <forax at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20211028/24fde99a/attachment-0001.htm>


More information about the amber-spec-experts mailing list