<div dir="ltr">I would very much favor constraining what can be done inside an expression switch as sharply as we can.<div><br></div><div>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?<div><br></div><div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;font-size:small">  // compare this two-way choice</div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;font-size:small">  return status == ABC ? something() : somethingElse();</div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;font-size:small"><br></div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;font-size:small">  // to this three-way choice</div><div style="color:rgb(34,34,34);font-family:arial,sans-serif;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;font-size:small">  return status<span> </span><i>??</i><span> </span>{ ABC -> something(); DEF, XYZ -> somethingElse(); default -> somethingOther(); }</div><br></div><div>(stand-in syntax only)</div><div><br></div><div>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.</div><div><br></div><div>Something to consider is whether we want a construct that readability-conscious developers will use <i>only</i> 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</div><div><br></div><div>  Result r = methodCall(</div><div>      param1,</div><div>      param2,</div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">      status</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"> </span><i style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial">??</i><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial"> </span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">{</span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">        ABC -> something();</span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">        DEF, XYZ -> somethingElse();</span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">        default -> somethingOther();</span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:small;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">      });</span><br class="gmail-Apple-interchange-newline"><br></div><div>I can see that usage at least being debatable, while I suspect we might frown on it all spelled out with `switch` and `case`....?</div><div><br></div><div>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.</div><div><br></div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 2, 2018 at 8:12 AM, Brian Goetz <span dir="ltr"><<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks for bringing this up.  I remember it being discussed once before, but I don't think we acted on it.<br>
<br>
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.)<br>
<br>
A sensible extension of this is no "return" from a switch expression either:<br>
<br>
    int foo(int x) {<br>
        return switch (x) {<br>
            case 1 -> 2;<br>
            case 2 -> 4;<br>
            case 3 -> 8;<br>
            default: return Integer.MAX_VALUE;<br>
        }<br>
    }<br>
<br>
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?<br>
<br>
    void foo(int x, int y, int z) {<br>
        TOP:<br>
        switch (z) {<br>
            case 1:<br>
                int i = switch (x) {<br>
                    case 1 -> 2;<br>
                    case 2:<br>
                        switch (y) {<br>
                            case 1: return;<br>
                            default: break TOP;<br>
                        }<br>
                }<br>
        }<br>
    }<br>
<br>
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?<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
<br>
<br>
<br>
On 3/2/2018 9:30 AM, Remi Forax wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hi all,<br>
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,<br>
i wonder if it's not simpler to disallow break label (and continue label) inside an expression switch.<br>
<br>
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.<br>
<br>
enum Result {<br>
   ONE, MANY<br>
}<br>
<br>
Result result(String[] args) {<br>
   ONE: for(String s: args) {<br>
      return switch(s) {<br>
        case "several":<br>
        case "many":<br>
          break MANY;<br>
        case "one":<br>
          break ONE;<br>
        default:<br>
          continue;<br>
      };<br>
   }<br>
   throw ...;<br>
}<br>
<br>
Rémi<br>
</blockquote>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif"><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px"> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px"> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px"> <a href="mailto:kevinb@google.com" target="_blank">kevinb@google.com</a></span></div></div></div></div></div></div></div>
</div>