<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Thanks Brian and Holo TSW (in other post) for your thoughtful responses.<div class=""><br class=""></div><div class="">I stand enlightened.<br class=""><div class=""><br class=""></div><div class="">My takeaway is that sealed types are not only not special, but that they have <br class=""><div class="">common and important use-cases<span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class=""> </span><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">(e.g. parser and json mapping) that indeed </span></div><div class=""><font color="#000000" class=""><span style="caret-color: rgb(0, 0, 0);" class=""><u class="">depend on</u> the kind of scalability that catchall labels provide, to avoid </span></font></div><div class=""><font color="#000000" class=""><span style="caret-color: rgb(0, 0, 0);" class="">e</span>veryone<span style="caret-color: rgb(0, 0, 0);" class="">’</span>s (rightly) loathed boilerplate and verbosity.</font></div><div class=""><font color="#000000" class=""><span style="caret-color: rgb(0, 0, 0);" class=""><br class=""></span></font></div><div class=""><font color="#000000" class="">Probably </font><font color="#000000" class="">Holo’s </font><span style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0);" class="">linter solution suffices.</span></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div><blockquote type="cite" class=""><div class="">On Apr 9, 2023, at 20:18, Brian Goetz <<a href="mailto:brian.goetz@oracle.com" class="">brian.goetz@oracle.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class="">

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" class="">

<div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">
I understand why you were motivated to make this suggestion.  But, I think the restriction you propose is overly restrictive.  
<div class=""><br class="">
</div>
<div class="">First let me amplify on your motivation, as this was an important motivation in the design of this feature: a switch that is exhaustive without a catch-all case is better than a switch that is exhaustive with one.  This is not because you don’t
 have to write the catch all case when you cover all the cases, though that is a nice side benefit.  It is because you get _better type checking_.  The compiler verifies your intent of exhaustiveness, and triggers an error if this is undermined by later additions
 to an enum or sealed class.  A default sweeps the sin under the rug.  </div>
<div class=""><br class="">
</div>
<div class="">So, you say, if better type checking is better, why not force everyone to get that better type checking by being exhaustive the honest way?  This is where things start to go off; there are too many legitimate use cases that this excludes.  </div>
<div class=""><br class="">
</div>
<div class="">First, consider the case where you have a large set of choices (such as tokens in a parser), but you only want to act on a few of them.  Switch is a good tool for this:</div>
<div class=""><br class="">
</div>
<div class="">    status = switch (nextToken) { </div>
<div class="">        case OPEN_PAREN -> …</div>
<div class="">        case IDENTIFIER -> …</div>
<div class="">        default -> throw new ParseException(“Expecting identifier or parentheses”);</div>
<div class="">    }</div>
<div class=""><br class="">
</div>
<div class="">This code is fine!  It is clear what is going on — we’re expecting one of two tokens, and anything else is an error.  Is the user helped by being required to list the other 72 tokens explicitly instead of a catch-all?  Is the code made more readable?
  </div>
<div class=""><br class="">
</div>
<div class="">Another example is the common pattern of a switch with two clauses, which is often more appropriate than an if:</div>
<div class=""><br class="">
</div>
<div class="">    boolean shouldStop = switch (color) { </div>
<div class="">        case RED -> true;</div>
<div class="">        default -> false;</div>
<div class="">    }</div>
<div class=""><br class="">
</div>
<div class="">Yes, this could be a ternary, but this pattern is pretty useful and pretty clear, and ternaries don’t scale.  Having to list out YELLOW and GREEN in the second case, even though there are only two, would not be an improvement.  </div>
<div class=""><br class="">
</div>
<div class="">I think what tripped you up was you extrapolated from a set of examples where you really were handling all, or nearly all, of the cases.  But switches are useful when you only want to handle one or two cases specially too.  </div>
<div class=""><br class="">
</div>
<div class="">
<div class=""><br class="">
<blockquote type="cite" class="">
<div class="">On Apr 8, 2023, at 10:09 AM, Robert <<a href="mailto:roberts14@cablelink.at" class="">roberts14@cablelink.at</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">
<div class="">Hi all, newbie here.  </div>
<div class=""><br class="">
</div>
<div class="">First off — loving Amber features.</div>
<div class=""><br class="">
</div>
<div class="">Now, a *very narrow* observation about how JDK 20 handles sealed type selector expressions.</div>
<div class="">(Code snippet below.)</div>
<div class=""><br class="">
</div>
<div class="">If a sealed type S later grows its list of permitted subtypes at some point, </div>
<div class="">how should the compiler handle switch blocks with S as selector?</div>
<div class=""><br class="">
</div>
<div class="">In the absence of a catchall label (i.e. <span style="caret-color: rgb(0, 0, 0);" class="">“case default -> ...” or “case S s -> ...”) ,</span></div>
<div class=""><span style="caret-color: rgb(0, 0, 0);" class="">the compiler already correctly issues an error that coverage is incomplete.</span></div>
<div class=""><span style="caret-color: rgb(0, 0, 0);" class=""><br class="">
</span></div>
<div class=""><span style="caret-color: rgb(0, 0, 0);" class="">But if the block ended with a catchall label, the compiler is silent; the best that</span></div>
<div class=""><span style="caret-color: rgb(0, 0, 0);" class="">can be hoped-for is that the coder throws a defensive exception in the catchall label </span></div>
<div class=""><span style="caret-color: rgb(0, 0, 0);" class="">(and hope that it is triggered in testing).</span></div>
<div class=""><span style="caret-color: rgb(0, 0, 0);" class=""><br class="">
</span></div>
<div class="">
<div class=""><font class=""><span style="caret-color: rgb(0, 0, 0);" class="">Suggestion</span></font>:</div>
</div>
<div class=""><br class="">
</div>
<div class="">Compiler should *disallows* catchall statements in switch blocks that use a sealed type </div>
<div class=""><b style="font-style: normal;" class=""><u class="">in the switch selector expression</u></b>.  Note that this special case does not affect all the </div>
<div class="">other non-sealed-type selectors (e.g. Object o), and appears (to me) to strengthen the</div>
<div class="">safety-value of sealed types in this particular scenario (similar to enums).  </div>
<div class=""><br class="">
</div>
<div class="">
<div class="">All in Java’s spirit of <span style="caret-color: rgb(0, 0, 0);" class="">“least surprise”.</span></div>
</div>
<div class=""><br class="">
</div>
<div class="">Cheers, </div>
<div class="">Robert</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<div class="">PS. reported behavior confirmed using jshell in JDK 20:</div>
<div class=""><br class="">
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">
<div class="">
<div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; font-size: 18px;" class="">
<span style="font-variant-ligatures: no-common-ligatures" class="">jshell --enable-preview</span></div>
</div>
<div class="">
<div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; font-size: 18px;" class="">
<span style="font-variant-ligatures: no-common-ligatures" class="">|  Welcome to JShell -- Version 20</span></div>
</div>
<div class="">
<div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo; font-size: 18px;" class="">
<span style="font-variant-ligatures: no-common-ligatures" class="">|  For an introduction type: /help intro</span></div>
</div>
</blockquote>
<div class=""><br class="">
</div>
<div class="">on the following:</div>
<div class=""><br class="">
</div>
<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class="">
<div class="">sealed interface S permits S.X, S.Y, S.Z, S.NEWBIE {</div>
<div class=""><br class="">
</div>
<div class="">final class X implements S {};</div>
<div class=""><br class="">
</div>
<div class="">final class Y implements S {};</div>
<div class=""><br class="">
</div>
<div class="">final class Z implements S {};</div>
<div class=""><br class="">
</div>
<div class="">final class NEWBIE implements S {};</div>
<div class=""><br class="">
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>public static void main(String [] sa) {</div>
<div class=""><br class="">
</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>   S something = new NEWBIE();</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>   System.out.println(</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>switch (something) {</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>case null -> 0;</div>
<div class="">        <span class="Apple-tab-span" style="white-space:pre"></span>case X x -> 1;</div>
<div class="">        <span class="Apple-tab-span" style="white-space:pre"></span>case Y y -> 2;</div>
<div class="">        <span class="Apple-tab-span" style="white-space:pre"></span>case Z z -> 3;</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>case S s -> -1;</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>// case default -> -1;</div>
<div class=""><span class="Apple-tab-span" style="white-space:pre"></span>});</div>
<div class="">    <span class="Apple-tab-span" style="white-space:pre"></span>};</div>
<div class="">}</div>
</blockquote>
<div class=""><br class="">
</div>
</div>
</div>
</blockquote>
</div>
<br class="">
</div>
</div>

</div></blockquote></div><br class=""></div></div></div></body></html>