3 ms·
Nah. Java checked exceptions failed because they weren't values and were impractical to use in generic code. The lesson isn't that you shouldn't put errors in y
by lmm 1y ago
Nah. Java checked exceptions failed because they weren't values and were impractical to use in generic code. The lesson isn't that you shouldn't put errors in your type system, it's that you should put them fully in your type system and make them as easy to use as regular types.
- vips7L 1y agoThey also failed because Java never made them easy to work with. If you faced a checked error that you couldn't handle it is impractical to uncheck them. You have to write a shit ton of boilerplate. A a; try { a = someThrowingFn(); } catch (AException ex) { throw new RuntimeException(ex); } It sucks. In Swift this is simply: val a = try! someThrowingFn(); Kotlin is moving towards having both unchecked exceptions (panics) and errors as values. I think its absolutely the correct decision. They're also including an easy way to panic when you can't handle an error: val a = someThrowingFn()!!; The other thing that I think made checked exceptions worse in the beginning was the lack of pattern matching and sealing with exceptions. Being able to exhaust all the different types of a particular error is really important if you want to properly respond. If you had a meaningless top level exception like IOException you couldn't effectively determine what actually happened and everyone just defaulted to unchecking it. Nowadays it's a little better if you seal your exception hierarchy: sealed abstract class SomeException extends Exception permits A, B { final class B extends SomeException {} final class C extends SomeException {} } try { someThrowingFn(); } catch (SomeException ex) { switch (ex) { case A a -> iCanHandleA(a); case B b -> throw new IllegalStateException(b); // can't handle this one } } Hopefully that becomes even better with the exceptions in switch [1] proposal: switch (someThrowingFn()) { case throws A a -> .. case throws B b -> .. } The real big issue like you said is that they're not completely in the type system. Especially when it comes to lambdas; you need to invent a Result<T, E> type every time you want to work with lambdas. Obviously all of these things are solvable with library code, try! is easily some static panic function; it sure would be nice to not have to write them. Overall I'm hopeful that with the overall programming community moving back towards checked errors that the OpenJdk team will invest in making checked exceptions better, but only time will tell. [0] github.com/Kotlin/KEEP/blob/main/proposals/KEEP-0441-rich-errors-motivation.md [1] https://openjdk.org/jeps/8323658 https://openjdk.org/jeps/8323658
- pjmlp 1y agoYet I regularly miss them when coding in C# and Typescript. I also used the C++ exception specifiers, which people keep forgetting is where Java's idea came from, alongside other languages like Modula-3.
- lmm 1y ago> I also used the C++ exception specifiers The legendary only feature so bad it was actually removed from C++? Those exception specifiers?
- pjmlp 1y agoYou forget that many C++ developers would also remove exceptions and RTTI if they gathered enough votes. If that is the point your trying to make. I on the contrary, would rather use the full language without dialects. And the feature worked, unlike export templates or C++ GC, also removed.