Retiring Checked Exceptions Was: Throwing Functions

John Hendrikx hjohn at xs4all.nl
Tue Nov 15 12:15:27 UTC 2022


I just wanted to add an observation here.

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.

The simplest example are streams.  When you write:

        Stream<URI> createStream() {
             return List.of("file:/xyz").stream().map(URI::new);  // 
throws URISyntaxException
        }

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.

Then in a completely unrelated part of the code you may use this stream:

        stream.toList();

There is no sign of the lambda, toList() doesn't declare checked 
exceptions, but this can now throw URISyntaxException.

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.

--John

------ Original Message ------
>From "Stephen Colebourne" <scolebourne at joda.org>
To "Amber dev" <amber-dev at openjdk.java.net>
Date 15/11/2022 10:41:15
Subject Re: Retiring Checked Exceptions Was: Throwing Functions

>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:
>
>* 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.
>* 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.
>* All closures are implicitly declared with lone throws. Thus, all 
>closures can throw checked and unchecked exceptions without declaring 
>the checked ones.
>
>
>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.
>
>Various alternative mechanisms are in use today:
>* additional functional interfaces such as ThrowableFunction
>* utilities like Unchecked.wrap(ThrowableSupplier) which convert 
>checked to unchecked
>* hacks like "sneaky throw"
>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.
>
>Stephen
>
>
>[1] 
>https://blog.joda.org/2010/06/exception-transparency-and-lone-throws_9915.html?m=1
>
>On Mon, 14 Nov 2022, 23:09 Archie Cobbs, <archie.cobbs at gmail.com> 
>wrote:
>>On Mon, Nov 14, 2022 at 4:52 PM <forax at univ-mlv.fr> wrote:
>>>I'm proposing to demote checked exceptions to make them second class 
>>>citizen because this practically what they are.
>>>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.
>>
>>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.
>>
>>>What if checked exceptions work like unchecked casts ?
>>
>>This sounds like a much more promising direction to go in.
>>
>>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".
>>
>>E.g. something like this??
>>
>>public <T> void execute(@PassThroughCheckedExceptions Supplier<T> 
>>getter) {
>>     return getter.get();
>>}
>>
>>public InputStream openFile(File file) throws IOException {
>>     this.execute(FileInputStream::new);
>>}
>>
>>-Archie
>>
>>--
>>Archie L. Cobbs
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20221115/083aaaa8/attachment-0001.htm>


More information about the amber-dev mailing list