Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Because you can't capture the evaluation of a function as a value, or write the type of it. E.g. try to write a generic function that takes a list and a callback, and applies the callback to every element of the list. Now what happens if your callback throws a checked exception? It doesn't work and there's no way to make it work, you just have to write another overload of your function and copy/paste your code. Now what happens if your callback throws two checked exceptions? It doesn't work and there's no way to make it work, you just have to write another overload of your function and copy/paste your code. And you'll never guess what happens if your callback throws three checked exceptions!


Make the signature of your generic callback "throws Throwable". It's generic; it should never care about the specific types that the callback can throw.

(Except that then you have to decide what your generic function is going to do if the callback throws an exception...)


> Make the signature of your generic callback "throws Throwable". It's generic; it should never care about the specific types that the callback can throw.

> (Except that then you have to decide what your generic function is going to do if the callback throws an exception...)

Exactly. Presumably you don't want to handle them and want to throw them up to the caller. But now your function has to be "throws Throwable" rather than throwing the specific exception types that the callback throws.


By doing that you lose all the benefits of checked exceptions. If you have checked exceptions everywhere the compiler will tell you when an exception is not handled and in turn you can ensure you handle it.

Of course in general the manual effort to do that in a large code base ends up too hard and so in the real world nobody does that. Still the ideal is good, just the implementation is flawed.


In that case you can use the lombok @SneakyThrows annotation that converts a checked exception to a runtime exception


what is "it doesn't work" ? The exception is part of the type, so it doesn't typecheck unless all callbacks are of type "... throws Exception"? What's the problem with that? It's not generic enough, i.e. the problem is Java generics are too weak to write something like "throws <T extends Exception>"? (Forgive me, it's been 13 years since I wrote java and only briefly, the questions are earnest)

edit, so like `@throws[T <: Exception] def effect[T](): Unit` or something, how is it supposed to work?


You can't be polymorphic between not throwing and throwing, or between throwing different numbers of exceptions. You have to write something like:

    <R> List<R> map(Function<? super T,? extends R> mapper) { ... }
    <R, E1 extends Throwable> List<R> map(FunctionThrows1<? super T,? extends R, E1> mapper) throws E1 { ... }
    <R, E1 extends Throwable, E2 extends Throwable> List<R> map(FunctionThrows2<? super T,? extends R, E1, E2> mapper) throws E1, E2 { ... }
and so on until you get bored.


Ah because there is no way to express E1 | E2 as a type parameter?


Yeah. Ironically the JLS includes a complete specification of what the type E1|E2 is, because if you write a catch block that catches both then that's the type of what you catch, there's just no syntax for it.


ah!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: