Expression switch - an alternate proposal

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Apr 13 07:17:40 UTC 2018



----- Mail original -----
> De: "Cay Horstmann" <cay.horstmann at sjsu.edu>
> À: "Brian Goetz" <brian.goetz at oracle.com>, "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-dev" <amber-dev at openjdk.java.net>
> Envoyé: Vendredi 13 Avril 2018 00:57:20
> Objet: Re: Expression switch - an alternate proposal

[...]

> I also don't understand Rémy's remark that a traditional break inside a
> switch expression is disallowed. What rules out
> 
>         case BAKED_POTATO:
>               Toppings t = new Toppings();
>               t.add(SOUR_CREAM);
>               t.add(CHEESE);
>               int count = 0;
>               while (true) {
>                  if (count == 10) break; else count++;
>                  t.add(BACON);
>               }
>               break t;
> 
> Or more horrifyingly,
> 
>         case BAKED_POTATO:
>               Toppings t = new Toppings();
>               t.add(SOUR_CREAM);
>               t.add(CHEESE);
>               int count = 0;
>               while (true) {
>                  if (count == 10) break t; else count++;
>                  t.add(BACON);
>               }
> 

both codes are valid,
what you can not do is break/continue/return through an expression switch.

loop: for(;;) {
  var foo = switch(bar) {
    case 0:
      break loop;  // invalid
    default:
      break 3;     // ok
  }
}

> Is there a restriction on what can go into the semicolon-separated list
> of statements in the case label of an expression switch? I couldn't see
> one in the JEP. And if not, what happens if there is a return? A break
> without value? A continue?

the current draft spec is here
  http://cr.openjdk.java.net/~gbierman/switch-expressions.html

you will find sentences like:
  "If a break statement with an Expression is contained in a switch, while, do, or for statement which itself is enclosed in the break target, or is enclosed by a lambda body which itself is enclosed in the break target, then a compile-time error occurs."
or
  "A continue statement is not permitted to transfer control through a switch expression. If the continue target contains a switch expression which itself encloses the continue statement, a compile-time error occurs." 

> 
> Cheers,
> 
> Cay

cheers,
Rémi

> 
> 
> Le 12/04/2018 à 05:48, Brian Goetz a écrit :
>> I think Remi has it exactly right here: this is a pedagogical blessing
>> in disguise -- as long as we can let go our of pre-existing notions of
>> how it ought to be taught.
>> 
>> The switch statement is nasty and complicated in multiple ways; surely
>> you don't want to teach that first if you have a choice. So start with
>> the simplified form of the switch expression:
>> 
>>      topping = switch (food) {
>>          case BURGER -> KETCHUP;
>>          case SAUSAGE, ASPARAGUS -> MUSTARD;
>>          case ICE_CREAM -> FUDGE;
>>          default -> NOTHING;
>>      }
>> 
>> Students should be able to grasp this immediately; if its one of the
>> things on the left, pick the thing on the right.  You can get a long way
>> with this.
>> 
>> Eventually you will come across a situation where the right-hand side is
>> not a simple expression.  Then you can teach them the escape hatch for
>> adding statements into the mix:
>> 
>>      topping = switch (food) {
>>          case BURGER -> KETCHUP;
>>          case SAUSAGE, ASPARAGUS -> MUSTARD;
>>          case ICE_CREAM -> FUDGE;
>>          case BAKED_POTATO:
>>              Toppings t = new Toppings();
>>              t.add(BACON);
>>              t.add(SOUR_CREAM);
>>              t.add(CHEESE);
>>              t.add(BACON);  // not a typo
>>              break t;
>>          default -> NOTHING;
>>      }
>> 
>> You can explain that "break" in a switch is like "return" in a method.
>> While the "spelling" might seem weird, the concept is not hard.
>> 
>> Now, when you need to, you can teach the switch statement in all its
>> glory.  They've already seen switching; they've already seen breaking;
>> what's left it to explain fallthrough (no way around this) and the lack
>> of exhaustiveness.
>> 
>> 
>> Which is to say:
>> 
>>   - New users can probably learn the concepts better by adding them in
>> one at a time; first simple expression switches, then adding in break,
>> then statement switches.
>> 
>>   - Existing users, who have already been through the gauntlet of
>> learning fallthrough, will necessarily learn it in the opposite order,
>> but they should be able to recognize that break means the same thing it
>> always has, so there are still relatively few new concepts here.
>> 
>> This seems like a pretty good pedagogical story either way!
>> 
>> 
>> 
>> On 4/12/2018 3:23 AM, Remi Forax wrote:
>>> ----- Mail original -----
>>>> De: "Cay Horstmann" <cay.horstmann at sjsu.edu>
>>>> À: "amber-dev" <amber-dev at openjdk.java.net>
>>>> Envoyé: Jeudi 12 Avril 2018 06:50:35
>>>> Objet: Re: Expression switch - an alternate proposal
>>>> I've thought about this more and in the end decided to speak up. Over
>>>> the years, I explained a substantial number of Java features to a very
>>>> large number of people, and I generally have a pretty good idea of where
>>>> people struggle. Anonymous inner classes, wildcards, constructor
>>>> references, the unnamed module, you name it. With all of these features,
>>>> I knew I had my work cut out explaining them, but I wasn't too bothered.
>>>>
>>>> I am bothered by the proposed expression switch syntax.
>>>>
>>>> When I read these discussions about colons vs. arrows, I fear that they
>>>> mask a much bigger issue. I do not think that there is significant
>>>> transfer from the existing switch statement to what we want to achieve
>>>> with expression switch. The matching part is similar, but the control
>>>> flow is not.
>>> the control flow of an expression switch is a subset of the control
>>> flow of a statement switch because it's an expression.
>>>
>>>> Maybe I am wrong. If there has been user testing that confirms that
>>>> programmers properly transfer their knowledge of statement switch to
>>>> expression switch with the "break x" syntax, that's great, and I'll shut
>>>> up. In absence of such evidence, I would urge (1) to make expression
>>>> switch visibly different from statement switch and (2) have an ironclad
>>>> justification for "break x" or abandon it. It has tension with labeled
>>>> break and classic break which can be present inside a branch of an
>>>> expression switch. Teaching a break/return analogy does not seem any
>>>> easier than teaching about block expressions.
>>> You can not have a break label (or a continue) inside a switch
>>> expression, again it's an expression, it's like ?:, you can have a
>>> break label into it.
>>>
>>> I disagree that teaching block expressions is as easy that teaching
>>> break expression, with block expressions, you also have to teach why
>>> you can not use it anywhere else in Java.
>>> The break expression does not have this issue. BTW, i think it's easy
>>> in term of teaching to teach the switch expression first and then to
>>> teach the statement switch given that the expression switch semantics
>>> is a subset of the statement switch semantics.
>>>
>>>> Cheers,
>>>>
>>>> Cay
>>>>
>>>>
>>> Rémi
>>>
>>>>
>>>> Le 10/04/2018 à 13:59, Stephen Colebourne a écrit :
>>>>> On 10 April 2018 at 09:02,  <forax at univ-mlv.fr> wrote:
>>>>>>>> Basically, your proposal is to use -> eveywhere, i think i prefer
>>>>>>>> the opposite,
>>>>>>>> do not use arrow at all.
>>>>> Current Oracle proposal:
>>>>> statements = colon
>>>>> expression = colon, with arrow for expressions
>>>>>
>>>>> Alternate proposal:
>>>>> statements = colon
>>>>> expression = symbol-that-isnt-colon
>>>>>
>>>>> Remi proposal:
>>>>> statements = colon
>>>>> expression = colon
>>>>>
>>>>> If the goal is a unified switch expression, Remi proposal wins. It is
>>>>> dead simple and very consistent.
>>>>>
>>>>>>> This is a reasonable alternative, but I don't think it would be very
>>>>>>> popular.  I think people will really love being able to write:
>>>>>>>
>>>>>>>       case MONDAY -> 1;
>>>>>>>       case TUESDAY -> 2;
>>>>>>>
>>>>>>> and will be sad if we make them write
>>>>>>>
>>>>>>>       case MONDAY: break 1;
>>>>>>>       case TUESDAY: break 2;
>>>>> Meh. Three more characters.
>>>>>
>>>>> Yet:
>>>>> - Avoids the arrow having a conflict of meaning with lambda.
>>>>> - No mixed arrows & colons
>>>>> - Much more consistent.
>>>>> - Minimal change from existing switch.
>>>>> - Less to learn.
>>>>> Win, win, win.
>>>>>
>>>>> So while I'd still choose to have a separate symbol for expression and
>>>>> statement switches (because of my #1 goal), I'm also pretty fine with
>>>>> the Remi proposal (because my #2 goal).
>>>>>
>>>>> In fact, what the discussion has informed me is that my #1 and #2
>>>>> goals are the wrong way around. Getting rid of the mixed arrows and
>>>>> colons is now more important to me than understanding the context in a
>>>>> large switch.
>>>>>
>>>>> Stephen
>>>>>
>>>>
>>>> --
>>>>
>>>> Cay S. Horstmann | http://horstmann.com | mailto:cay at horstmann.com
>> 
> 
> 
> --
> 
> Cay S. Horstmann | http://horstmann.com | mailto:cay at horstmann.com


More information about the amber-dev mailing list