4 ms·
I couldn't disagree more with the point about checked exceptions. Pretty much everyone else has essentially agreed that checked exceptions were a mistake. They
by cletus 4y ago
I couldn't disagree more with the point about checked exceptions. Pretty much everyone else has essentially agreed that checked exceptions were a mistake. They leak implementation details and/or pollute your interface. Practically speaking, they don't force you to deal with exceptions. They force you to catch them. Anyone who has done Java in the real world has encountered:
try {
// do stuff
} catch (SomeException e) {
// do nothing, maybe log it
}
I strongly agree the verbosity is a non-issue. Any modern IDE just fills this in for you. Yes more verbose syntax for getters/setters would be nice but it's not a big deal.
But there's one point I wanted to highlight. Every language that comes after Java should've learned Java's lessons and some didn't.
C# quite famously did. C# really is Java 2.0. No checked exceptions, reified generics (rather than type erasure) and some cool stuff too (eg LINQ, partial classes).
Other languages (eg Go, Rust) largely moved away from exceptions entirely. Personally I agree with this. Exceptions are a false economy that devolve into control flow that's hard to follow (eg Java has a parse number from string that throws a ParseException if the parsing fails and that's just not an exception).
But the big one is dependencies. Every external dependency system that came after Mavaen should be at least as good and many aren't. I'm looking at you, Go. This was a shocking omission for something aimed at being a better systems programming language (which it never would be as a GC language but that's another story).
But Java is proven, mature and sufficient. That's why it's still used.
- ars 4y agoYah, I've always felt that the "checked" should not have been part of the exception type, rather it should have been part of the throw: throw checked new Exception(); Then the caller knows there is a special reason to handle this exception, and it's also easy to write a tiny wrapper to neutralize the check, if needed. For example: failure to open a file could be nothing major in one case (just return null), needs to be handled in another, or should cause the entire application to exit. This depends on what file was opened - but it does NOT depend on the type of error.
- shlurpy 4y agoRusts error handling is almost identical to checked exceptions in practice. The reason it works is because there is no real equivalent to easily handle-able unchecked exceptions, and because macros and sum types make it very easy to wrap a lower level error in your higher level error and rethrow. Basically, checked exceptions could have worked, if they were the only type, and had better ergonomics of use, and a language culture that emphasized correctness more. Checked exceptions were wrong for Java, but that does not mean they are wrong universally.
- jamal-kumar 4y agoGo's module and vendoring system sure was kind of a rocky transition. It left a lot of older projects in the lurch in terms of adaptability without having to take extra time for reworking a few things, especially if they used some third party system like dep or whatever and just never got updated after, which kind of crunched against the design goals of forward compatibility. I think they just kind of aimed to keep it as simple as possible in line with other design goals of the language and tooling, which is fine for its use case. It would have helped a lot if they had done this from the start, though. I don't really think that Go was intended to be a systems level programming language, I've never used it that way personally. I think of it as specialized towards being an excellent applications level programming language with rich-enough system level interfaces where necessary. People who do stuff like programming a bootable OS in go aren't doing it because they intend to develop it into something everyone will use, it's done more like an exercise.
- pwdisswordfish0 4y agoHere's an excellent series where in a 2003 interview, Anders Hejlsberg discusses lots of these types of things and more. <https://www.artima.com/intv/anders.html https://www.artima.com/intv/anders.html>
- kaba0 4y agoChecked exceptions are an exact analog for result types. If you have an `int parseInt(String s) throws ParseException` function it is basically equivalent to `parseInt(s: String): Result<Integer, ParseError>`. Hell, if anything, it is better — it is automatically “unboxed” for you, and in case of an error you get the sane default choice of bubbling said exception up (rust’s ? macro does the same, but it is much less ergonomic). It has the added benefit of including stack traces, which makes it actually possible to do anything with unhandled error cases and is of utmost importance. I’m not claiming that Java’s execution of checked exceptions is good, it unfortunately does have a few inconsistencies (lambdas don’t operate well with them, also inheritance is not a good match for exceptions), but it was pretty universally ditched and I think it very well deserves another chance.
- piva00 4y agoMy issue with checked exceptions in Java is that it becomes another branch of control flow. It increases cognitive load to keep in mind that exceptional cases are basically running a `GOTO` that you have to keep track of. I think they can have its place but operating well with lambdas would be a must... If Java supported a multi-value return, like Go and Python do, and control flow was based on `var a, err = obj.exec()` or some other syntax that could work nicely with Streams and the functional features of Java I wouldn't have an issue with checked exceptions. A multi-return for errors with checked exceptions would even allow the compiler to narrow down all the possible `err` types you could get, automatically generate a Java 17 `switch()` to parse through all the possible cases of checked exceptions. It could help a lot with error handling.