On 01.03.2018 16:39, Jesper Steen Møller wrote:
[...]
|int numLetters = switch (day) { case MONDAY, FRIDAY, SUNDAY -> 6; case TUESDAY -> 7; case THURSDAY, SATURDAY -> 8; case WEDNESDAY -> 9; };|

with

|case LABEL -> expression;|

essentially sugar for

|case LABEL: break expression;|

to make this straight.

int result = switch (s) {
    case "Foo":
        break 1;
    case "Bar":
        break 2;
    default:
        System.out.println("Neither Foo nor Bar, hmmm...");
        break 3;
}

is the long form of

int result = switch (s) {
    case "Foo" ->  1;
    case "Bar" ->  2;
    default:
        System.out.println("Neither Foo nor Bar, hmmm...");
        break 3;
}

The default here has no shorter version, because they are using a statement and need to return something in the expression. I understood the proposal, that both forms are valid and can be mixed.

There is a few things I dislike...and most of all it is the break command here.

int accumulator = 0
LOOP: for (T element : someList) {
  accumulator += switch (element.type) {
    case PLUS_ONE -> +1;
    case MINUS_ONE -> -1;
    case ERROR:
      break LOOP;
    case default -> 0
  }
}

with the idea that element.type is an enum... But my problem is with break LOOP. Is LOOP the label LOOP, or is it a constant/variable?

If they need the break only to break out of the switch, then why not capitalize on lambdas?

int accumulator = 0
LOOP: for (T element : someList) {
  accumulator += switch (element.type) {
    case PLUS_ONE -> +1;
    case MINUS_ONE -> -1;
    case ERROR -> {break LOOP;}
    case default -> 0
  }
}

This would be much more aligned with what Java has, then you would naturally use return if you are required to use statements. Plus it would align more with what is in JEP-305 with for example "case Integer i -> i+1". I would not even support the column version for a switch expression.

And then of course there is the basic problem: you have to have a single expression. Not many people are actually like using switch-case, I do, but rarely this is for me in the break expression style as described. For me this whole construct makes no sense without JEP-305 and for that JEP you do not need some of the variants described at all. Let us not forget that the switch-object is limited to quasi constants such as strings, enum values and integers. They do not have the isCase construct, thus no variant to do an equals based check. Even with JEP-305, this is not changed. In theory you could do something like this in Java:

accumulator += switch-case (element.type, new Case(PLUS_ONE, -> +1),
    new Case(MINUS_ONE, -> -1),
    new Case(-> 0));

Then switch-case can be a generic function, that checks the Case objects for the supplied matched and on equality executed the provided lambda. This variant would realize the break expression version and would not support labels or return statements (only as part of the lambda). But it would be possible to do, even extensible to do more than just that - and allow lambdas for the matcher as well.

[...]> Now, this being Groovy, the cases should surely support the extended
"isCase"-support, as described so well here: http://mrhaki.blogspot.dk/2009/08/groovy-goodness-switch-statement.html

So, three questions remain:
1) Useful or not?

for me not, it is one of the constructs I would not use. And given the sentiment against switch-case by many programmers, they would not either.

2) This Java compatibility - is it still a thing? I remember a similar proposal a little while back, but this would align better with Java.

IMHO there is still work in that bug report to align better with Java ;) For Groovy yes... if they add it to Java, we add it to Groovy... but not because it is good or useful, just for compatibility

3) This could be implemented using existing AST's if we /_really_/ want to, but it would be clumsy. This AST transformer compatibility - is it still a thing?

Sure it is a thing, but I doubt it can be implemented using the AST. switch-case is a statement, and while we have expression-statements (expressions as statements) we do not have statements as expressions. And I think none of the constructs in the bug would even pass the parser. Without parser, no AST.

Meaning to implement this, you have to change the grammar,then you have to introduce a new expression type and extend the visitors to support it. And finally you may be able to match it to the switch statement, but:

int f(n, m) {
  int res = switch (n) {
    case 0 -> m+1;
    default -> switch(m) {
      case 0 -> f(n-1,1)
      default -> f(n-1, f(n,m-1))
    }
  }
  return res;
}

This will not be easy, because you will need a temporary variable if you want to simulate this with the statement form... And frankly not sure it is worth it compared to a "real" implementation in the compiler, which will not have to use it. Of course you would normally not use switch-case for this, it is just an example for a complex expression having a nested switch-case-expression.

In summary: I would wait for what the Java guys decide in the end.

bye Jochen

Reply via email to