You (the programmer) still have to handle it. If I (as a person) don't know how to handle the exception, passing it up the call stack doesn't solve the problem, it just moves it to somewhere else. The problem is that I don't know where it should be handled, because it was exposing cryptic and obscure exception types that probably make sense to someone who really understands cryptography. I don't, so I just can't use that library.
If those were runtime exceptions, my program would just crash on error, which is the default I wanted. I didn't want to pollute my code with error handling stuff just to try out some simple functionality. If they were runtime exceptions, I could learn to use the code from the ground up, not by having to understand the whole thing at once.
That's exactly the point: not everyone along the method stack is forced to deal with it, only the one caller that knows how to handle it.
> The problem is that I don't know where it should be handled
Then don't handle it at all and let it crash the program. But at least you didn't add boiler plate simply bubbling up an Err at every level of the stack frames.
> If those were runtime exceptions, my program would just crash on error, which is the default I wanted
Sometimes it is, sometimes it isn't. Some exceptions should crash your program (runtime exceptions), others should be handled (checked exceptions). Languages that take correctness seriously should offer you both options.
I'm not talking about handling the error, I'm talking about boilerplate. In order to get the program to even crash on error, I had to handle 4 different kinds of exceptions. I'm as much a fan of expciciteness as anyone, but there's a difference between explicit and verbose. And there's a lot to be said for constructs that don't force you to indent your code every time you call a function.
My goal wasn't to write correct code, it was to test something out. To get comfortable with the library and the task. Checked exceptions get in the way of that.
>Languages that take correctness seriously should offer you both options.
Rust and Haskell take correctness seriously and offer neither. Checked exceptions make perfect sense in terms of ensuring correctness, but they are awful for usability and they are not the only way to achieve correctness.
>Some exceptions should crash your program (runtime exceptions), others should be handled (checked exceptions).
Shouldn't the user determine that, not the implementor? Why should any exceptions not be checked?
Because there are exceptions you can't do anything about (e.g. OutOfMemoryException) and exceptions that you don't know what to do with (e.g. an NPE where you didn't expect it).
NPE is the poster child for an unchecked exception: if you know your code is throwing an NPE here, just fix it instead of catching the NPE.
If those were runtime exceptions, my program would just crash on error, which is the default I wanted. I didn't want to pollute my code with error handling stuff just to try out some simple functionality. If they were runtime exceptions, I could learn to use the code from the ground up, not by having to understand the whole thing at once.