←back to thread

873 points belter | 2 comments | | HN request time: 0s | source
Show context
Terr_ ◴[] No.42946597[source]
> Java is a great language because it's boring [...] Types are assertions we make about the world

This is less of a mind-was-changed case and more just controversial, but... Checked Exceptions were a fundamentally good idea. They just needed some syntactic sugar to help redirect certain developers into less self-destructive ways of procrastinating on proper error handling.

In brief for non-Java folks: Checked Exceptions are a subset of all Exceptions. To throw them, they must be part of the function's type signature. To call that function, the caller code must make some kind of decision about what to do when that Checked Exception arrives. [0] It's basically another return type for the method, married with the conventions and flow-control features of Exceptions.

[0] Ex: Let it bubble up unimpeded, adding it to your own function signature; catch it and wrap it in your own exception with a type more appropriate to the layer of abstraction; catch it and log it; catch it and ignore it... Alas, many caught it and wrapped it in a generic RuntimeException.

replies(13): >>42946899 #>>42946979 #>>42947054 #>>42947147 #>>42947485 #>>42947568 #>>42948130 #>>42948153 #>>42948666 #>>42951688 #>>42952999 #>>42953957 #>>42984777 #
dustingetz ◴[] No.42946899[source]
remind me why they don’t work? because “throws Exception” propagates virally to every method in the codebase?
replies(3): >>42947046 #>>42948691 #>>42949347 #
lmm ◴[] No.42948691[source]
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!
replies(2): >>42948974 #>>42949045 #
dustingetz ◴[] No.42948974[source]
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?

replies(1): >>42949296 #
lmm ◴[] No.42949296{3}[source]
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.
replies(2): >>42949471 #>>42951118 #
1. catlifeonmars ◴[] No.42949471{4}[source]
Ah because there is no way to express E1 | E2 as a type parameter?
replies(1): >>42957772 #
2. lmm ◴[] No.42957772[source]
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.