<html><body><div style="font-family: arial, helvetica, sans-serif; font-size: 12pt; color: #000000"><div><br></div><div><br></div><hr id="zwchr" data-marker="__DIVIDER__"><div data-marker="__HEADERS__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;"><b>From: </b>"Ron Pressler" <ron.pressler@oracle.com><br><b>To: </b>"Remi Forax" <forax@univ-mlv.fr><br><b>Cc: </b>"Brian Goetz" <brian.goetz@oracle.com>, "Tom" <tom_l64@hotmail.com>, "amber-dev" <amber-dev@openjdk.org><br><b>Sent: </b>Sunday, March 5, 2023 8:37:41 PM<br><b>Subject: </b>Re: Language feature to improve checked exceptions<br></blockquote></div><div data-marker="__QUOTED_TEXT__"><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
Checked exceptions don’t intrinsically "colour your function” any more (or less) than a return type. Java’s ability to helpfully polymorphise over checked exceptions, however, is more limited.
</blockquote><div><br></div><div>That's factually correct but it's like saying that C# Task or JS Promise don't intrinsically color your function because they are return types.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Unchecked exceptions let you insert functions that are unaware of the exception in between the function that may raise an exception and the function that recover from that exception.<br data-mce-bogus="1"></div><div>So checked exceptions compared to unchecked exceptions color your function.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>Rémi<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><blockquote style="border-left:2px solid #1010FF;margin-left:5px;padding-left:5px;color:#000;font-weight:normal;font-style:normal;text-decoration:none;font-family:Helvetica,Arial,sans-serif;font-size:12pt;">
<div class=""><br class="">
</div>
<div class="">— Ron<br class="">
<div><br class="">
<blockquote class="">
<div class="">On 5 Mar 2023, at 18:37, Remi Forax <<a href="mailto:forax@univ-mlv.fr" class="" target="_blank">forax@univ-mlv.fr</a>> wrote:</div>
<br class="Apple-interchange-newline">
<div class="">
<div class=""><br class="Apple-interchange-newline">
<br class="">
</div>
<hr id="zwchr" class="">
<div class="">
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;" class="">
<b class="">From:</b>"Brian Goetz" <<a href="mailto:brian.goetz@oracle.com" class="" target="_blank">brian.goetz@oracle.com</a>><br class="">
<b class="">To:</b>"Tom L" <<a href="mailto:tom_l64@hotmail.com" class="" target="_blank">tom_l64@hotmail.com</a>>, "amber-dev" <<a href="mailto:amber-dev@openjdk.org" class="" target="_blank">amber-dev@openjdk.org</a>><br class="">
<b class="">Sent:</b>Sunday, March 5, 2023 3:24:38 AM<br class="">
<b class="">Subject:</b>Re: Language feature to improve checked exceptions<br class="">
</blockquote>
</div>
<div class="">
<div class="">
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;" class="">
<font class="" size="4"><font class="" face="monospace">I have some sympathy for the desire to optimize catch-and-wrap; doing this the regular way is indeed</font></font><font class="" size="4"><font class="" face="monospace"><font class="" size="4"><font class="" face="monospace">syntactically</font></font>painful
 when the actual business logic is small (which it often is.)  Catch-and-wrap works well as an abstraction idiom when turning a low-level exception (e.g., IOException) into a higher-level one (e.g., XMLException); as higher-level library-code delegates to lower-level
 library code, it will want to remap low-level errors to higher-level ones.  (Particularly interesting is catch-and-wrap at the method declaration level, with some sort of `throws X as Y`, as it represents the catch-and-wrap rules declaratively rather than
 imperatively.)<br class=""><br class="">
However, the examples you give of catch-and-wrap are not really catch-and-wrap; they are catch-and-pretend-they-didn't-happen (by turning checked exceptions into unchecked ones.)  While this would surely be popular among the "checked exceptions suck" crowd,
 this is not making error handling more reliable, it is just making it easier to ignore errors.</font></font></blockquote>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<div class="">A remark, a catch-and-pretend-they-didn't-happen is just a catch-and-wrap without the enclosing context.</div>
<div class=""><br class="">
</div>
<div class="">For example, you can see<br class="">
</div>
<div class="">  List<String> foo() {<br class="">
</div>
<div class="">    ...<br class="">
</div>
<div class="">    List<String> list = stream.map(it -> {</div>
<div class="">        try {<br class="">
</div>
<div class="">          return IO.something(it);<br class="">
</div>
<div class="">        } catch(IOException e) {<br class="">
</div>
<div class="">          throw new UncheckedIOException(e);<br class="">
</div>
<div class="">        }<br class="">
</div>
<div class="">      }).toList(),<br class="">
</div>
<div class="">    return list; <br class="">
</div>
<div class="">  }<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">but foo() is called like this<br class="">
</div>
<div class="">  List<String> list;<br class="">
</div>
<div class="">  try {<br class="">
</div>
<div class="">    list = foo()<br class="">
</div>
<div class="">  } catch(UncheckedIOException e) {<br class="">
</div>
<div class="">    throw e.getCause();<br class="">
</div>
<div class=""> }<br class="">
</div>
<div class=""><br class="">
</div>
<div class=""><br class="">
</div>
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;" class="">
<font class="" size="4"><font class="" face="monospace"><br class="">
The Result approach is both safe and honest (and can be implemented today without language help), but is more foreign to Java developers.  It operates by moving the side-channel result into the main channel, which enables monadic composition (turning a partial
 operation into a total one returning a Success|Fail union).  With pattern matching in the language, this gets even more attractive.  Still, I suspect that most of the "checked exceptions suck" crowd wouldn't thank us for kicking off the massive, decade-long
 migration from checked exceptions to the Either monad. </font></font></blockquote>
<div class=""><br class="">
</div>
<div class="">From Java the language POV, returning Either or using a checked exception both side of the same coin, there are semantically equivalent.<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">As a proud member of the "checked exception suck in Java" crowd. The "in Java" is important. Checked exceptions do not suck in the vacuum, it suck in Java because on a higher level is goes against the freedom of composition and because on a lower
 level the Java type system does not handle them well, no union type (only precise rethrow), no proper way to bundle exceptions into a type parameter.</div>
<div class=""><br class="">
</div>
<div class="">It's the colored function problem [1].  Checked exceptions aka the Result monad does not suck in Rust. Because inherently Rust is a language that consider library composition less important than precise lifetime tracking or asynchronous calls
 tracking, the whole language relies on colored functions. But Java is not Rust, freedom of composition, freedom to use any libraries whenever it was written, is an important part of the language. That's why Java has a GC, lightweight threads, lambdas, erased
 generics or the concept of binary backward compatibility. All those features enable free easy composition.</div>
<div class=""><br class="">
</div>
<div class="">Sadly checked exception in Java colors functions, they create an unnecessary artificial barrier to library compositions. That's why they suck in Java.<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">regards,<br class="">
</div>
<div class="">Rémi<br class="">
</div>
<div class=""><br class="">
</div>
<div class="">[1]<a href="https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/" class="" target="_blank">https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/</a><br class="">
</div>
<div class=""><br class="">
</div>
<blockquote style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica, Arial, sans-serif; font-size: 12pt;" class="">
<font class="" size="4"><font class="" face="monospace"><br class=""><br class=""><br class=""></font></font><br class="">
<div class="moz-cite-prefix">On 3/4/2023 6:49 PM, Tom L wrote:<br class="">
</div>
<blockquote cite="mid:AM7PR04MB70932A45D29F52A4435206B088B09@AM7PR04MB7093.eurprd04.prod.outlook.com" class="">
<div class="WordSection1" style="page: WordSection1;">
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
Hello, it's the first time I send an email here, I have no idea how things work, so I hope I am doing things somewhat correctly.</div>
<p class="MsoNormal" style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;">
 </p>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
I wanted to make a suggestion about exceptions :</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
Checked exceptions are used as a meant of a second return type, which shouldn't happen in most cases, and then, depending of what the caller wants to do, it will handle it in a certain way. So in some sort, a checked exception is like part of the return type,
 like you would have a Result<Success, Failure>, compared to unchecked exception in java which are just supposed to be bugs.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
But this feature causes some burden, so much so that some languages, even languages compiling to java (ie kotlin) got rid of checked exceptions, and other languages like Rust use a Result<Success, Failure> which, which, with enough language constructs, can
 be quite good.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
While I agree that not having checked exceptions nor Result but instead only unchecked ones would be a bad idea, because it would mean that a part of the return type is unknown, which we wouldn't want in a strongly typed language, I believe some action needs
 to be taken.</div>
<p class="MsoNormal" style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;">
 </p>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
In my opinion, one of its burdens is caused by the try-catch language feature :</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
String text;</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
try {</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
                text = Files.readString(somePath);</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
} catch(IOException ex) {</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
                throw new UncheckedIOException(ex);</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
}</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
//do something with text</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
This is a common example, of how you would use it : you want to read a string, and an IO error shouldn't happen, so you fail-fast</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
The reason why I didn't use text inside the catch, is because the catch should only be for this specific exception, and also it would add another level of nesting, which would start to hurt when other ifs or try-catches appear.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
This code is boilerplate and is error-prone, since you always have to repeat the same lines, it is also weird for any non java programmer.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
And this is far from being the worst, because another common example is with streams, since you can't throw checked exception, you have to handle each time, in each stream operation, and even if you wrap this code in methods and use method references, it's
 still far less readable than having a short lambda where you see exactly what the stream is doing.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
If checked exceptions were instead a Result type, a solution to this problem would be to make a unwrap() method (like in Rust, or like with Java's Optional#orElseThrow())</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
String text = Files.readString(somePath).unwrap();</div>
<p class="MsoNormal" style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;">
 </p>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
So my suggestion is that, since catching is a language feature, it can only be dealt with another language feature :</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
String text = Files.readString(somePath) throw IOException ex as new UncheckedIOException(ex);</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
If this method throws an IOException, it will rethrow it as an UncheckedIOException.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
About the syntax, I used "throw" since it's an already used keyword, but depending of the meaning, it could be "catch" or whatever, and "as" could be "->" if using a contextual keyword is too much.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
This code could even be simplied as the following with new methods or language features, in the future :</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
String text = Files.readString(somePath) throw IOException ex as ex.unchecked();</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
String text = Files.readString(somePath) throw IOException as unchecked;</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
etc.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
Unchecked part could either be the same exception except the compiler ignores it (I know this is possible since it's possible to throw a checked exception as an unchecked), the idea is that since you are telling the compiler that if an exception happens, then
 it should fail-fast, then the compiler should be able to say "ok, I trust you".</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
An alternative would be that the unchecked simply wrap it in a RuntimeException or a specific unchecked exception.</div>
<p class="MsoNormal" style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;">
 </p>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
So, what's the point of this, does it only serve this use case ?</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
So first, is it important to note that it isn't just for checked -> fail-fast, but also checked -> some other checked, when exception conversion is needed, which can be useful, and also unchecked -> checked/unchecked, for example if an API only provides an
 unchecked like Integer#parseInt.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
Now about the use case : this syntax, isn't just a compressed try-catch, it's also an expression, which is very important, because not only you can very clearly handle this kind of cases, but it can provide easy to read, concise code in lambdas  and assignments,
 for example :</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
try (var files = Files.list(path) {</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
                return files.filter(this::matcher)</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
                                               .map(p -> Files.readString(p) throw IOException as unchecked)//Possible syntax Files::readString throw IOException as unchecked ?</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
                                               .toList();</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
}</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
And in the future, a new method could be added for streams called .continueOnFailure(IOExcepion.class) (or UncheckedIOException if the unchecked wraps the exception instead of marking it as unchecked) for example, which would continue even if there is an exception.</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
An additional syntax could also be provided for cases where catching is used as an if else :</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
OptionalInt parseInt(String s) {</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
                return OptionalInt.of(Integer.parseInt(s)) catch NumberFormatException -> OptionalInt.empty();            // Using -> syntax here instead of "as" to show that it can also make sense</div>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
}</div>
<p class="MsoNormal" style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;">
 </p>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
I hope it can fix this unholy war of checked exceptions which never seem to advance.</div>
<p class="MsoNormal" style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;">
 </p>
<div style="margin: 0cm; font-size: 11pt; font-family: Calibri, sans-serif;" class="">
Sincerely.</div>
</div>
</blockquote>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
<br class="">
</div><br></blockquote></div></div></body></html>