<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<br>
<blockquote type="cite" cite="mid:CALMUwcp7KHQGnmf=jRMG4ML9oRPr4EY28n_HG7A3aeTEAy0arA@mail.gmail.com">
<div dir="ltr">
<div>Please don't require default to be at the bottom. There
are some situations where the default case can recover from
unhandled input with a satisfactory response. See the code
below. </div>
</div>
</blockquote>
<br>
Yes, but such cases happen almost exclusively in conjunction with
fallthrough, and case patterns can't fall through (because then the
bindings might not be DA.) Right now, we make a distinction
between "legacy switch" (old types, constant case labels, no
patterns) and other switches (expressions, or statements with
patterns.) We have to carve out the code you cite below for
compatibility reasons, but we don't have to let it infect the new
world. <br>
<br>
The things we know from "old switch" are not necessarily
representative of the new world....<br>
<br>
<blockquote type="cite" cite="mid:CALMUwcp7KHQGnmf=jRMG4ML9oRPr4EY28n_HG7A3aeTEAy0arA@mail.gmail.com">
<div dir="ltr">
<div>The default case logs the problem and falls through to
return false. If the "NO" case were more complex and if
default were required at the bottom, then the requirement
would cause duplicate code. In some situations, the duplicate
code could be extracted to a separate method. In other
situations, there are too many local variables being changed
by the case in a loop to make it possible.<br>
</div>
<div><br>
</div>
<div>public static boolean isYes(String value)</div>
<div>{</div>
<div> switch (value)</div>
<div> {</div>
<div> case "YES":</div>
<div> return true;</div>
<div><br>
</div>
<div> default:</div>
<div> LOGGER.error("Unhandled value: {}", value);</div>
<div> // break;<br>
</div>
<div><br>
</div>
<div> case "NO":</div>
<div> return false;<br>
</div>
}<br>
<div>}<br>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Sun, Jun 19, 2022 at 12:27
PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div> <br>
<blockquote type="cite">
<div dir="ltr">
<div>As always, your answers are well thought out and
have good points. I wonder if it would make sense to
write up a design page, document the choices and why
one choice was picked over another. Then, have your
team review it and then the world via JEP. This way
future and other language designers can benefit from
the information. If some future designer wants to
change the language, they can read the document and
realize all the constraints and hidden pits.<br>
</div>
</div>
</blockquote>
<br>
We did something like that for a few of the features (see
the FAQ / style guides Stuart Marks put together for Local
Variable Type Inference, and for Text Blocks.) It would be
great to have them for all the features, and keep them
updated as new questions come up and get answered here. In
a perfect world, we would! But sometimes there are too many
things to do. We'd welcome contributions on this. <br>
<br>
<blockquote type="cite">
<div dir="ltr">I love that Java will require
exhaustiveness in switch and provide the feature for
more data types. It will do one of two things. I can
either put all the cases and know that all situations
are handled, OR I can add a default and add error
handling for an unexpected situation. It will help me
write more robust code without having to write as many
unit tests. As you pointed out, I will spend less time
debugging and furthermore writing a unit test to
reproduce the problem.<br>
</div>
</blockquote>
<br>
Exactly! And another benefit is that someone reading the
code can tell whether you intended the switch to cover all
the cases, or not, just by looking for a default / total
case. (Right now the positioning of `default` is
unconstrained, as it always was, but we may require it float
to the bottom, to make it easier to find the catch-all
case.) <br>
<br>
A subtle point about exhaustiveness that people don't often
realize is that, when switching over a domain with
exhaustiveness information (enums or sealed types), it is
better *not* to have a default, and instead let the compiler
insert a throwing default to catch separate compilation
errors. Because then, if someone adds a new enum constant
or subtype later, you find out next compile time, rather
than at run time. <br>
<br>
(Which reminds me of another thing to add to my response to
Hunor on the topic: because we add a throwing default to
total switches that don't already have a catch-all case,
this would be yet another subtle and surprising difference
between switch expressions and switch statements.)<br>
<br>
<blockquote type="cite"><br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Sun, Jun 19, 2022
at 7:42 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px
0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex"><br>
> I haven't played with switch expressions, but I
think of them kind of <br>
> like this but much more performant...<br>
><br>
> int y = x == 0 ? 0 : x == 1 ? 2 : x == 2 ? 4 : x
== 3 ? 6;<br>
<br>
I encourage you to broaden how you think of this.
Yes, they might be <br>
more performant (though they might not be -- a good
compiler can chew <br>
this up too), but that is is both a secondary, and a
dependent, <br>
benefit. The alternative is:<br>
<br>
int y = switch (x) {<br>
case 0 -> 0;<br>
case 1 -> 2;<br>
case 2 -> 4;<br>
default -> 6;<br>
}<br>
<br>
which I'm sure everyone finds more readable.<br>
<br>
The primary benefit is that you are using a simpler,
more constrained <br>
concept. A chain of ternaries or if-else can have
arbitrary and <br>
unrelated predicates, and offers less opportunity for
exhaustiveness <br>
checking. It involves unneeded repetition ("x ==
<something>") which is <br>
a place for errors to hide in. The fact that each
predicate in the <br>
chain above is of the form `x == <something>` is
neither mandated nor <br>
checked nor even obvious at first glance; this makes
it harder to read <br>
and more error-prone; you could easily fumble this for
"z == 2" and it <br>
would be hard to notice. Whereras a switch has a
distinguished operand; <br>
you are saying "this operand should match one of these
cases", and <br>
readers know it will match *exactly* one of those
cases. That is a more <br>
constrained statement, and by using a more specialized
tool, you can <br>
make the calculation more readable and less
error-prone.<br>
<br>
The performance benefit, if there is one, comes from
the fact that you <br>
have performed a semantic "strength reduction", which
is potentially <br>
more optimizable. But that's a totally dependent
benefit, one which <br>
flows from having written more clear, specific code in
the first place.<br>
<br>
<br>
</blockquote>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</blockquote>
<br>
</body>
</html>