<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>"John Hendrikx" <hjohn@xs4all.nl><br><b>To: </b>"Stephen Colebourne" <scolebourne@joda.org>, "Amber dev" <amber-dev@openjdk.java.net><br><b>Sent: </b>Tuesday, November 15, 2022 1:15:27 PM<br><b>Subject: </b>Re[2]: Retiring Checked Exceptions Was: Throwing Functions<br></blockquote></div><div><style id="css_styles"><!--blockquote.cite { margin-left: 5px; margin-right: 0px; padding-left: 10px; padding-right:0px; border-left: 1px solid #cccccc }
blockquote.cite2 {margin-left: 5px; margin-right: 0px; padding-left: 10px; padding-right:0px; border-left: 1px solid #cccccc; margin-top: 3px; padding-top: 0px; }
a img { border: 0px; }
li[style='text-align: center;'], li[style='text-align: center; '], li[style='text-align: right;'], li[style='text-align: right; '] { list-style-position: inside;}
body { font-family: 'Segoe UI'; font-size: 12pt; }
.quote { margin-left: 1em; margin-right: 1em; border-left: 5px #ebebeb solid; padding-left: 0.3em; }
--></style></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;"><div><span>I just wanted to add an observation here.</span></div><div><span><br></span></div><div><span>I now have seen several ideas here that seem to point to a solution which just allows lambda's to throw checked exceptions (with a warning or automatically converted to unchecked), but what I find odd is that this wouldn't solve anything at all. These functions are almost by definition not used or called immediately, and so the actual checked exception can occur in a totally unrelated part of the code that may not be prepared to handle it: this unrelated code would not be declaring any exceptions and the compiler would give no warnings or errors, but a checked exception can now pop up there uninvited.</span><br></div><br><div>The simplest example are streams. When you write:</div><br><div> Stream<URI> createStream() {</div><div> return List.of("file:/xyz").stream().map(URI::new); // throws URISyntaxException</div><div> }</div><br><div>There is no need to declare anything, and any warnings or errors would make no sense. Allowing the above method to declare "URISyntaxException" is just plain incorrect, leaving you to write a catch block (or rethrow) to deal with something that can't happen.</div><br><div>Then in a completely unrelated part of the code you may use this stream:</div><br><div> stream.toList();</div><br><div>There is no sign of the lambda, toList() doesn't declare checked exceptions, but this can now throw URISyntaxException. </div><br><div>IMHO solutions that just allow you to pretend the checked exception doesn't exist are going to just muddy the waters further, and don't really solve the problem at all. They just make it easier to hide the problem, and in doing so, create new problems. I think it is possible to do better and find a solution that doesn't come with a new set of problems.</div></blockquote><div><br></div><div>You have to compare with what is done currently, when you write this in your IDE<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div><div> Stream<URI> createStream() {</div><div> return List.of("file:/xyz").stream().map(URI::new); // throws URISyntaxException</div><div> }</div></div><div><br data-mce-bogus="1"></div><div>the IDE will happily transform the code to<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div> <div> Stream<URI> createStream() {</div><div> return List.of("file:/xyz").stream().map(s -> {</div><div> try {<br> return new URI(s);<br> } catch(URISyntaxException e) {</div><div> throw new RuntimeException(e);<br> }<br></div><div> });<br></div><div> }</div><br data-mce-bogus="1"></div><div>which is in my opinion worst than considering URISyntaxException as unchecked, because here the type of the exception is lost by wrapping it into a runtime exception.<br data-mce-bogus="1"></div><div><br data-mce-bogus="1"></div><div>So yes, the proposed solution is far from ideal, but i believe a warning is a better answer than wrapping all checked exceptions into unchecked ones. <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;"><br><div>--John</div></blockquote><div><br></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;">
<br>
<div>------ Original Message ------</div>
<div>From "Stephen Colebourne" <<a href="mailto:scolebourne@joda.org" target="_blank">scolebourne@joda.org</a>></div>
<div>To "Amber dev" <<a href="mailto:amber-dev@openjdk.java.net" target="_blank">amber-dev@openjdk.java.net</a>></div>
<div>Date 15/11/2022 10:41:15</div>
<div>Subject Re: Retiring Checked Exceptions Was: Throwing Functions</div><br>
<div id="x29b0fd941062455"><blockquote cite="CACzrW9CZYpqsStPNJFJipBgzPPVY+8uc0RUrGTBmsn6MXLFXtw@mail.gmail.com" class="cite2">
<div dir="auto"><div dir="auto">I outlined simple, practical approach to this when lambdas were first added to Java [1]. Much of the blog post above is no longer especially interesting, but the basic "lone throws" concept still is. The key part is repeated in these three bullet points:</div><div dir="auto"><br></div><div dir="auto"><div dir="auto">* Any method may have a throws keyword without specifying the types that are thrown ("lone-throws"). This indicates that any exception, checked or unchecked may be thrown. Once thrown in this manner, any checked exception flows up the stack in an unchecked manner.</div><div dir="auto">* Any catch clause may have a throws keyword after the catch. This indicates that any exception may be caught, even if the exception isn't known to be thrown by the try block.</div><div dir="auto">* All closures are implicitly declared with lone throws. Thus, all closures can throw checked and unchecked exceptions without declaring the checked ones.</div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto">I suspect it is too late for the last bullet point to be adopted, but the first two would IMO still be hugely beneficial to Java. The point here is not to reject the idea of checked exceptions, but to provide a convenient way to convert/handle them when they are not what you want.</div><div dir="auto"><br></div><div dir="auto">Various alternative mechanisms are in use today:</div><div dir="auto">* additional functional interfaces such as ThrowableFunction</div><div dir="auto">* utilities like Unchecked.wrap(ThrowableSupplier) which convert checked to unchecked</div><div dir="auto">* hacks like "sneaky throw"</div><div dir="auto">My argument is that there is a very clear use case in the global corpus of Java code for a mechanism to convert/handle checked exceptions more like unchecked. And that this would be a good language feature, given that it can be done without threatening those who appreciate checked exceptions.</div><div dir="auto"><br></div><div dir="auto">Stephen</div><div dir="auto"><br></div><div dir="auto"><br></div><div>[1] <a href="https://blog.joda.org/2010/06/exception-transparency-and-lone-throws_9915.html?m=1" target="_blank">https://blog.joda.org/2010/06/exception-transparency-and-lone-throws_9915.html?m=1</a><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, 14 Nov 2022, 23:09 Archie Cobbs, <<a href="mailto:archie.cobbs@gmail.com" target="_blank">archie.cobbs@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr">On Mon, Nov 14, 2022 at 4:52 PM <<a href="mailto:forax@univ-mlv.fr" rel="noreferrer" target="_blank">forax@univ-mlv.fr</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)">I'm proposing to demote checked exceptions to make them second class citizen because this practically what they are.<br><div><div>The problem is that the status quo is pushing people to use runtime exceptions instead of exceptions because checked exception do not compose well, exactly what we both do not want.<br></div></div></div></div></blockquote><br><div>I totally agree that the lack of composibility (composibleness?) is a problem. But I don't agree that ALL of the blame for that problem rests on checked exceptions. After all, checked exceptions have been around a lot longer than lambdas.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div style="font-family:arial,helvetica,sans-serif;font-size:12pt;color:rgb(0,0,0)"><div><div>What if checked exceptions work like unchecked casts ?</div></div></div></div></blockquote><br>This sounds like a much more promising direction to go in.</div><div class="gmail_quote"><br></div><div class="gmail_quote">All we want is a simple way to tell the compiler "I know this lambda can throw a checked exception, just pass it through instead of making this impossible to compile".</div><div class="gmail_quote"><br></div><div class="gmail_quote">E.g. something like this??<br></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace"><br></span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace">public <T> void execute(<span style="background-color:rgb(255,255,0)">@PassThroughCheckedExceptions</span> Supplier<T> getter) {<br></span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace"> return getter.get();<br></span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace">}</span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace"><br></span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace">public InputStream openFile(File file) throws IOException {</span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace"> this.execute(FileInputStream::new);<br></span></div><div class="gmail_quote" style="margin-left:40px"><span style="font-family:monospace">}<br></span></div><br><div>-Archie<br></div><div class="gmail_quote"><div> </div></div>-- <br><div dir="ltr">Archie L. Cobbs<br></div></div>
</blockquote></div></div></div>
</blockquote></div><br></blockquote></div></div></body></html>