Most active commenters
  • baq(7)
  • Terr_(4)
  • catlifeonmars(3)

←back to thread

873 points belter | 11 comments | | HN request time: 0.013s | source | bottom
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 #
baq ◴[] No.42947568[source]
> adding it to your own function signature

This is precisely why they are so bad: checked exceptions must not be allowed to be used outside the package (or jar, or whatever, just limit it) otherwise they cause non-local build failures in all dependencies. They're fine if you are developing the artifact that's going to be deployed.

replies(2): >>42949399 #>>42950468 #
catlifeonmars ◴[] No.42949399[source]
I think that’s more of a problem of changing the function signature. Not specific to checked exceptions.
replies(1): >>42949639 #
1. baq ◴[] No.42949639[source]
What's specific in checked exceptions is that if you don't handle or silently ignore the new exception, you must change the signature. Then your callers must do the same thing. Then their callers etc. sometimes right down to your public static void main.
replies(2): >>42949717 #>>42952933 #
2. catlifeonmars ◴[] No.42949717[source]
Yep, don’t change the function signature of depended on code. That’s the problem :)

It would be equally problematic to change the method name, or the argument arity or types (ignoring overloading for the moment).

It would be even more problematic if I kept the same function signature, but changed the meaning of the parameters. Then your breakage is silent.

replies(1): >>42950181 #
3. baq ◴[] No.42950181[source]
yes exactly, hence unchecked exceptions are the sane option.
replies(1): >>42951034 #
4. catlifeonmars ◴[] No.42951034{3}[source]
Doesn’t that just introduce a silent breaking change to your downstream consumers? That sounds worse.

It sounds ok from a library authors perspective but definitely not from a library consumer perspective.

A sane thing to do would be to do a version bump.

replies(1): >>42952002 #
5. baq ◴[] No.42952002{4}[source]
consider the standard library case - e.g. there's a new kind of exception because new storage or network technology demands it. you can't add it without breaking the build of everything everywhere effectively freezing the standard library version for people who don't have the means to fix their build. that's super duper bad.
replies(1): >>42953175 #
6. Terr_ ◴[] No.42952933[source]
And that is extremely good compared to the same function-writer adding or changing their non-checked exception, for which an 1+ levels removed consumer gets no warning at all until the pager goes off because the system broke in production.
replies(1): >>42953062 #
7. baq ◴[] No.42953062[source]
Unless the library upgrade is also fixing a 9.9 CVE.
replies(1): >>42953429 #
8. Terr_ ◴[] No.42953175{5}[source]
1. The standard library is special in many ways, particularly because it often isn't shipped along with your product and you can't always control what version is used. Just because something is problematic for those libraries doesn't mean it it's a bad idea everywhere else.

2. The difference between altering your un/checked exceptions is not whether consumers will have to react, but how it shows up and how badly you will ruin their day. A checked exception is unambiguously better. It will immediately break their build at the same time they ought to be expecting build-breaks, and the compiler will give them a clear and comprehensive list of cases to address. In contrast, an unchecked exception may let them compile but it will break their business in production, unpredictably.

replies(1): >>42953518 #
9. Terr_ ◴[] No.42953429{3}[source]
That same scenario (an emergency version-change to a direct dependency) could also remove a function that your code calls! Yet that does not mean mean compiler-checks are bad, or that the solution is to make a system that lets you yeet it into production anyway.

Look, I get it: Sometimes a Checked Exception defined in a niche spot "infects" higher-level code which adds it to their signatures, because nobody takes the time to convert it into something more layer-appropriate.

But that is the exact same kind of problem you'd also get when library's NicheCalculationResult class is trickling upwards without conversion too! However nobody freaks out over that one. Not because it's mechanically different, but because it's familiar.

replies(1): >>42953897 #
10. baq ◴[] No.42953518{6}[source]
Re 1) when the standard library becomes a major blocker for the runtime version upgrade many people are seriously angry, or depressed.

Re 2) that's what it must've sounded like in theory in the conference room when they were designing that part of the language. In practice, the upgrade of the library will never happen if it breaks the build. Production should catch all runtime exceptions and be able to restart itself gracefully anyway because cosmic rays don't make sense as checked exceptions.

11. baq ◴[] No.42953897{4}[source]
> That same scenario (an emergency version-change to a direct dependency) could also remove a function that your code calls!

absolutely, but the catch is it doesn't affect me transitively. the immediate caller must deal with the issue somehow. with exceptions, it is expected to not handle the ones you have no business handling, so you should change your signature. this propagates upwards and there is no layer of abstraction that can handle this problem without breaking the world. the only somewhat sane way is wrapping the new exception is something that you already handle - if that makes logical sense, which it very well might not.

> NicheCalculationResult class is trickling upwards

yes, and yes people do freak out, not sure why you think they aren't :)