<div dir="ltr"><div class="gmail_extra">Let me put in a negative vote here. I think checked exceptions are evil. They were one of these things that <b>sounded</b> really good in theory but have turned out in practice to make things worse—by far—than had they never existed.<br>
<br></div><div class="gmail_extra">When I have checked exceptions I have to check the exception signature of <b>each and every</b> predicate or function I call and do one of the following:<br><ol><li>Add the exception to my signature. The <b>whole point</b> of exceptions is to decouple error detection from error handling. They're intended to eliminate that whole thing in languages without them where you do something like if this error else if that error else if this other error else if yadda yadda yadda ad nauseum with each and every function call as you encounter conditions you can't deal with yourself but which something higher-up might be able to handle. Thus the default for most functions when exceptions enter the picture is to just pass them on up the chain to the right handler (which is often going to be the mainline code just shutting down cleanly with an error message). Being forced to add every two-bit trigger-pumping moron's exceptions into the predicate/function signature just clutters the interface with no real benefit. Further, if there's any changed in the exceptions downstream, <b>every predicate or function</b> in the chain above it has a commensurate signature change; one that has the capacity for essentially rewriting and recompiling your entire application because someone corrected a typo. (And this is all also beside the problem that it's all unwieldy anyway: if each function calls two other functions and each function has one possible exception declared, how long before you have a combinatorial explosion in your interface size?)</li>
<li>Catch-and-convert the exception. This is the common "solution" to the ever-expanding exception signature problem. try { ... } catch (Exception e) { throw MyGenericException(e); } is the typical pattern. Ever see those never-ending exception stack traces in Java code? This is why. Because people are forced to either handle or add each and every subordinate method's exception down the stack, and because adding each exception to the signature of each and every method is just unworkable, the "solution" is to catch any exception and wrap it in your own exception. This actually <b>worsens</b> the ability of upstream to handle the exception because you're now removing information that could be required to handle things properly. Consider this situation: at the low levels of your code opening the file fails because it doesn't exist. Some kind of exception (file_not_found, say) is thrown. If you're five layers of function/predicate calls down, and if each function/predicate call does this catch-and-convert, mainline code has to unwrap five exception type variables to get to the file_not_found exception instead of, you know, just catching file_not_found. catch some_generic_exception, then unwrap(some_generic_exception) then unwrap(unwrapped_generic_exception) then unwrap(unwrapped_unwrapped_generic_exception) and so on. Not only are you recreating the whole if this error else if that error else if that other error situation, you're making it worse by putting all of it in a single place. And you're cluttering up all the intervening functions/predicates with boilerplate catch-and-convert code to boot.</li>
</ol><p>Now let's look at composition. Checked exceptions completely and utterly break composition. The <b>whole point</b>, for example, of higher-order code is to decouple execution patterns from the specifics of execution. Let's consider a simple situation of mapping a function/predicate against a list. What exceptions should be declared on that mapping function? Well, I might do division in the passed-in function, so I'll need to catch divide by zero errors. So now my list mapping code has to declare divide by zero as a possible exception, even though there's <b>nothing</b> in its actual code that can do this. Now what happens if I'm mapping a function provided by some third-party that declares some_random_exception in its interface? Now my map has to somehow know about this third-party exception in advance and declare it in its interface. This is both clearly impossible and ridiculous. So what do I have to do instead? Oh, right. I'm back at catch-and-convert and I've just, once again, missed the entire point of how exceptions are supposed to simplify and ease error handling. Somewhere in this process I've just made composition, arguably the entire <b>point</b> of a good modern, declarative language, more difficult for no good reason. (Because most exceptions just get logged or used to generate an error message and a clean shutdown anyway.)</p>
<p>Now all this doesn't mean I'm opposed to the notion of having some way to check exception throwing and handling. I just don't think it should be part of the language. I'm going to invoke something better (IMO): external tooling.</p>
<p>Consider Erlang. Erlang is a dynamically typed language with an <b>external</b> static type checker (using an unusual kind of typing called "success typing", however). I think a static analysis <b>tool</b> would be a better fit for checking exceptions. This tool would read the source code and simply make reports on exception handling, spotting chains of code where exceptions bubble up to the main predicate and out without being handled. This would give you the purported benefits of checked exceptions without the liabilities of cluttering up a code base with endless ceremony (which lazy programmers <b>will</b> just turn into empty catch clauses anyway!).<br>
</p></div><div class="gmail_extra"><br>-- <br>"Perhaps people don't believe this, but throughout all of the discussions of entering China our focus has really been what's best for the Chinese people. It's not been about our revenue or profit or whatnot."<br>
--Sergey Brin, demonstrating the emptiness of the "don't be evil" mantra.
</div></div>