Disallowing break label (and continue label) inside an expression switch

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Mar 2 20:06:35 UTC 2018


Hi Kevin, 
i've already proposed to remove 'case' (using match instead of ??) 
see http://mail.openjdk.java.net/pipermail/amber-spec-experts/2017-December/000211.html 
and http://mail.openjdk.java.net/pipermail/amber-spec-experts/2017-December/000232.html 
but Brian did not like it :) 

Rémi 

> De: "Kevin Bourrillion" <kevinb at google.com>
> À: "Brian Goetz" <brian.goetz at oracle.com>
> Cc: "Remi Forax" <forax at univ-mlv.fr>, "amber-spec-experts"
> <amber-spec-experts at openjdk.java.net>
> Envoyé: Vendredi 2 Mars 2018 17:40:05
> Objet: Re: Disallowing break label (and continue label) inside an expression
> switch

> I would very much favor constraining what can be done inside an expression
> switch as sharply as we can.
> In fact, if we were designing the language from scratch, all at the same time,
> but having already decided the behavior of the conditional operators ?: ...
> might we not logically design this as similarly as possible to that?
> // compare this two-way choice
> return status == ABC ? something() : somethingElse();

> // to this three-way choice
> return status ?? { ABC -> something(); DEF, XYZ -> somethingElse(); default ->
> somethingOther(); }

> (stand-in syntax only)

> You could ideally think of ?: as sugar for the latter. Might we possibly be
> better off thinking of it this way, and not even worrying about multi-statement
> cases (you can always extract a method)? It seems like several of our woes
> disappear.

> Something to consider is whether we want a construct that readability-conscious
> developers will use only as the object of a return statement or variable
> assignment (which is what I think we have, currently), or one that they might
> comfortably use in-line in other circumstances, like

> Result r = methodCall(
> param1,
> param2,
> status ?? {
> ABC -> something();
> DEF, XYZ -> somethingElse();
> default -> somethingOther();
> });

> I can see that usage at least being debatable, while I suspect we might frown on
> it all spelled out with `switch` and `case`....?

> As a last point in its favor, `null` can be treated completely normally - if you
> didn't list `null ->` or `ABC, null ->`, etc., then use the default.

> On Fri, Mar 2, 2018 at 8:12 AM, Brian Goetz < [ mailto:brian.goetz at oracle.com |
> brian.goetz at oracle.com ] > wrote:

>> Thanks for bringing this up. I remember it being discussed once before, but I
>> don't think we acted on it.

>> I agree that expression switch is an expression, and it should either yield a
>> value or throw something; breaking out of the middle of an expression is not
>> something we have, nor does it seem necessary. (Though I'm sure clever folks
>> could come up with a good example where it would be convenient.)

>> A sensible extension of this is no "return" from a switch expression either:

>> int foo(int x) {
>> return switch (x) {
>> case 1 -> 2;
>> case 2 -> 4;
>> case 3 -> 8;
>> default: return Integer.MAX_VALUE;
>> }
>> }

>> Like conditionals, then, switch expressions would either yield a value (through
>> breaking) or throw. This seems consistent, but...what happens when we nest a
>> statement in a switch expression?

>> void foo(int x, int y, int z) {
>> TOP:
>> switch (z) {
>> case 1:
>> int i = switch (x) {
>> case 1 -> 2;
>> case 2:
>> switch (y) {
>> case 1: return;
>> default: break TOP;
>> }
>> }
>> }
>> }

>> Do we disallow the "break TOP" and return in the inner switch? IOW, does the
>> expression form a barrier through which control can only pass via break or
>> exceptions?

>> On 3/2/2018 9:30 AM, Remi Forax wrote:

>>> Hi all,
>>> as far as i remember, the current idea to differentiate between a break label
>>> and a break value is to let the compiler figure this out,
>>> i wonder if it's not simpler to disallow break label (and continue label) inside
>>> an expression switch.

>>> After all, an expression switch do not exist yet, so no backward compatibility
>>> issue, it may make some refactoring impossible but had the great advantage to
>>> do not allow a lot of puzzler codes like the one below.

>>> enum Result {
>>> ONE, MANY
>>> }

>>> Result result(String[] args) {
>>> ONE: for(String s: args) {
>>> return switch(s) {
>>> case "several":
>>> case "many":
>>> break MANY;
>>> case "one":
>>> break ONE;
>>> default:
>>> continue;
>>> };
>>> }
>>> throw ...;
>>> }

>>> Rémi

> --
> Kevin Bourrillion | Java Librarian | Google, Inc. | [ mailto:kevinb at google.com |
> kevinb at google.com ]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20180302/0b580689/attachment-0001.html>


More information about the amber-spec-experts mailing list