<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Aptos;
        panose-1:2 11 0 4 2 2 2 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:12.0pt;
        font-family:"Aptos",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
code
        {mso-style-priority:99;
        font-family:"Courier New";}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;
        mso-ligatures:none;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-CA" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt">My reading of the JEP is that this is that it’s about treating all the possible results of evaluating the selector uniformly – both the normal results and the exceptional ones.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">Being able to treat the results uniformly makes it easier to be precise about what exceptions should be handled in each way.  With today’s try/catch, there is no way to distinguish handling of an exception
 thrown by the selector from one due to the case handling code.  This JEP allows those two cases to be distinguished.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">As to refactoring, my impression is that the new case throws is a win as it allows the handling code to be scoped closer to the potential source of the exception.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">More responses in line.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="mso-margin-top-alt:0cm;margin-right:0cm;margin-bottom:12.0pt;margin-left:36.0pt">
<b><span style="color:black">From: </span></b><span style="color:black">amber-spec-experts <amber-spec-experts-retn@openjdk.org> on behalf of Tagir Valeev <amaembo@gmail.com><br>
<b>Date: </b>Saturday, April 20, 2024 at 4:01</span><span style="font-family:"Arial",sans-serif;color:black"> </span><span style="color:black">AM<br>
<b>To: </b>Angelos Bimpoudis <angelos.bimpoudis@oracle.com><br>
<b>Cc: </b>amber-spec-experts <amber-spec-experts@openjdk.java.net><br>
<b>Subject: </b>Re: Exception handling in switch (Preview)<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Dear experts,</p>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">looking into this proposal, I'm really not convinced that Java needs it. We already have try-catch statements, and it sounds strange to provide another way to express the same semantics. I don't see what the new
 construct adds, aside from a bit of syntactic sugar. On the other hand, it creates a new source of subtle bugs, especially when exceptions are unchecked. E.g., consider:</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">switch(a.b().c().d()) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">case ...</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">case throws RuntimeException ex -> handle(ex);</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">}</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Now, one may want to refactor the code, extracting a.b(), a.b().c(), or the whole a.b().c().d() to a separate variable for clarity, or to avoid a long line. </p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">This action is usually safe, and it was totally safe in switches so far (even with patterns and case null). Now, it's not safe, as exceptions thrown from the extracted part are not handled by the 'case throws'
 branch. </p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">I don't see a good way to perform this refactoring in a semantically equivalent way. The only possibility I see is to duplicate the exception handler in the external catch:</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">try {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  var ab = a.b();</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  switch(ab.c().d()) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  case ...</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  case throws RuntimeException ex -> handle(ex);</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  }</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">}</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">catch(RuntimeException ex) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  handle(ex); // duplicated code</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">}</p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">This doesn’t mean quite the same thing as the new try/catch block will catch RuntimeExceptions thrown by the “case …” in addition to those thrown by the selector (“ab.c().d()”).  I think we can use more switches
 to make the refactoring:<o:p></o:p></span></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">var ab = switch(a.b()) {</p>
<p class="MsoNormal">  case Object o -> o; // need more precise type than Object</p>
<p class="MsoNormal">  case throws RuntimeException ex -> handle(ex);</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal">switch(ab.c().d()) {</p>
<p class="MsoNormal">  case ...</p>
<p class="MsoNormal">  case throws RuntimeException ex -> handle(ex);</p>
<p class="MsoNormal"> }</p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">As switch selector does not allow using several expressions or to declare new variables, extract/inline refactorings can easily become very painful, or cause subtle bugs if not performed correctly. </p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Note that it's not a problem inside usual try-catch statement (*), as you can easily add or remove more statements inside the try-body.</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">(*) Except resource declaration, but it's rarely a problem, and in some cases it's still possible to extract parts as separate resources, because you can declare several of them</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">I think, instead of repurposing switch to be another form of try-catch we could add more love to try-catch allowing it to be an expression with yields in branches. The proposed JEP allows something like this:</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Integer toIntOrNull(String s) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  return switch(Integer.parseInt(s)) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">    case int i -> i;</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">    case throws NumberFormatException _ -> null;</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  }</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">}</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">But we are still limited by a single expression in the selector. An alternative would be</p>
</div>
<div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Integer toIntOrNull(String s) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  return try { yield Integer.parseInt(s); }</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">    catch(NumberFormatException _) { yield null; };</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">}</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Here, all kinds of refactorings are possible. And we actually don't need to express pattern matching, because we essentially don't need any pattern matching.</p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt">I’m not sure I follow the point of making try/catch an expression here.  We can write this code today with return:<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal">Integer toIntOrNull(String s) {</p>
<p class="MsoNormal">    try { return Integer.parseInt(s); }</p>
<p class="MsoNormal">    catch(NumberFormatException _) { return null; }</p>
<p class="MsoNormal">}</p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Also, note that some of the situations which are usually solved with exception handling in modern Java (e.g. Pattern.compile -> PatternSyntaxException, or UUID.fromString -> IllegalArgumentException, or Integer.parseInt
 above) will be covered in future by member patterns. So probably if we concentrate more on member patterns, people will need much less exception handling in business logic, and such an enhancement will be not so useful anyway? Speaking about the sample from
 the JEP, can we imagine something like this in the future (sic!) Java?</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">switch(future) {</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  case Future.cancelled() -> ...</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  case Future.interrupted() -> ...</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  case Future.failed(Exception ex) -> ... // no need to unwrap ExecutionException manually</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">  case Future.successful(Box b) -> ...</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">}</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">One more note about the JEP text. It's unclear for me whether 'case throw' branches could catch a residual result. More precisely, if MatchException happens, or NullPointerException happens (selector evaluated
 to null, but there's no 'case null'), can these exceptions be caught by the 'case throws' branches in the same switch?</p>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
<p class="MsoNormal">I think if the selector evaluates to “null”, then it is the switch, not the selector, that throws NPE so I wouldn’t expect a case throws NPE to handle that exception.  Similarly, a MatchException isn’t thrown by the selector, it’s a result
 of the exhaustive switch not matching (ie: remainder handling) so I’d similarly expect it not to trigger a case throws MatchException.  But happy to be corrected here.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">--Dan</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">With best regards,</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">Tagir Valeev.</p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
</div>
</div>
<p class="MsoNormal" style="margin-left:36.0pt"><o:p> </o:p></p>
<div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt">On Fri, Apr 19, 2024 at 3:05<span style="font-family:"Arial",sans-serif"> </span>PM Angelos Bimpoudis <<a href="mailto:angelos.bimpoudis@oracle.com">angelos.bimpoudis@oracle.com</a>> wrote:</p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt">
<div>
<div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">Dear spec experts,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">A while ago we discussed on this list about enhancing the
</span><code><span style="font-size:10.0pt;color:black">switch</span></code><span style="font-size:11.0pt;font-family:"Arial",sans-serif;color:black">​</span><span style="font-size:11.0pt;color:black"> construct to<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">support
</span><code><span style="font-size:10.0pt;color:black">case</span></code><span style="font-size:11.0pt;font-family:"Arial",sans-serif;color:black">​</span><span style="font-size:11.0pt;color:black"> labels that match exceptions thrown during evaluation of
 the<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">selector expression. A draft JEP for this feature is now available at:<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><a href="https://bugs.openjdk.org/browse/JDK-8323658" target="_blank"><span style="font-size:11.0pt">https://bugs.openjdk.org/browse/JDK-8323658</span></a><span style="font-size:11.0pt;color:black"><o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">Please take a look at this new JEP and give us your feedback.<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">Thanks,<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-left:36.0pt"><span style="font-size:11.0pt;color:black">Aggelos<o:p></o:p></span></p>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</body>
</html>