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