to summarize,
we enhance le old switch by adding comma separated list of case values and by 
adding null as a possible pattern, and a warning if there is no default or the 
default is not at the ends,
then we add an expression switch which extends the old switch as a poly 
expression with no fall through (make no sense), no weird scoping rules, the 
compiler emits an error if the switch is not exhaustive (need a default at the 
end apart for enums).

Right.

what i'm currently doing with switch is using statement switch + return as a 
poor's man expression switch

Very common!
I tend to refactor by introducing a method
Essentially, trying to make DA work for you.
But if we support expression block in the expression switch, the two forms are 
very close syntactically,
by example, can you find the difference between
   return switch(name) {
       case "red" -> {
         return Color.RED;
       };
       case "blue" -> {
         return Color.BLUE;
       };
       default -> {
         throw new AssertionError("invalid " + name);
       };
   };
and
   switch(name) {
       case "red": {
         return Color.RED;
       };
       case "blue": {
         return Color.BLUE;
       };
       default: {
         throw new AssertionError("invalid " + name);
       };
   };
this is far from obvious, and as a dev you have to because the semantics are 
differents.

The main difference is the unfortunate pun between local and nonlocal return.

I wonder if we should either make the syntactic difference more clear

Open to suggestions.

Reply via email to