4 ms·
Perhaps because the complexity budget of trying to get checked exceptions right is so high that no one even bothers to try. Once you find yourself able to just
by sreque 6y ago
Perhaps because the complexity budget of trying to get checked exceptions right is so high that no one even bothers to try. Once you find yourself able to just return values representing an ADT, then why bother? If the point of a checked exception is that the caller should try handling it immediately, then just return a value like IO<T> instead of return T but maybe throw IOException.
- ragnese 6y agoBut Java has no language support for dealing with a Try/Result type. It would be objectively worse than just using checked exceptions, IMO.
- sreque 6y agoIt's definitely not ideal, but I use Optional to replace nulls in Java and I think it works fine. Similarly you can return values that could represent an error. Or, you can throw an unchecked exception. Callers should be aware of all exceptions a method can throw, especially since those can include unchecked exceptions the compiler doesn't tell you about. Since the caller should do this work anyways, using unchecked exceptions is more than acceptable.
- ragnese 6y agoOptional is okay. Of course, you could still be a real jerk and return null instead of Optional<T> and the compiler won't warn me at all and I'll just get an NPE at run time... But it probably won't happen. The problem with Try/Result is that you still have to do manually unwrapping and/or early returns. Scala and Haskell have monad comprehensive to make this less noisy. Rust has the ? operator. Java has nothing. This makes your code WAY more noisy than having a try-catch inside your non-trivial function. In a proper world, callers should NOT be aware of all exceptions a function can throw. That's exactly the point of having checked and unchecked exceptions. Checked means the library author thought there is a chance that you might want to handle the exception locally. Unchecked means the library author does not want you to try to recover- they've already determined you're screwed.
- sreque 6y agoI don't think this is true in theory or in practice. Java's Integer.valueOf(String) throws an unchecked exception if it fails, and you should very much be aware of it and catch it in many situations. Also, in many situations, it doesn't make sense to catch IOException but rather let it propagate. The set of exceptions you should not be expected to catch is generally a very narrow subset of unchecked exceptions, like java.lang.LinkageError or NPE due to internal bug in the called method.
- ragnese 6y agoAck. Totally agree about Integer.valueOf. I think I agree about IOException, too. Definitely most other people agree that it should've been unchecked and that does seem reasonable, as long as it's really only thrown for "oh shit- someone unplugged the hard drive" errors. I still think that in theory, the distinction I articulated would be proper. I'd always prefer returning algebraic data types rather than checked exceptions if I were inventing a new language. But given that Java has nothing in the way of that, I'd still say that one should attempt to follow the hypothetical distinction I articulated, even if Java itself fails at it...
- Groxx 6y agoIt depends on your ADT implementation, but sometimes yes. E.g. Rust makes a pretty good case for not needing exceptions, with the `?` operator, implicit "into" conversions, and a `match` operator that allows returning from the func and not just from the match branch's closure. In a language without some or all of those (or without ADTs at all, you could have them just for exceptions for instance), ADT-matching to many specific types can get pretty onerous... or you need to do an equivalent to the "catch Exception -> throw RuntimeError" safety-erasing nonsense that this article is rightfully claiming is a problem. Shoving error-types into a separate bucket though often leaves you with a single "return" type, possibly also removing generics entirely, which is trivial to deal with in the happy path in all cases. Optimizing code for the happy path is one of the reasons people like exceptions, so that's potentially significant. --- edit: ah, no, IMO a large part of the point of exceptions at all (checked included) is that the caller can ignore it by forwarding it implicitly, punting it up the chain without effort. Checked largely just makes sure it's visible in your type signature so you cannot do that silently, unlike runtime exceptions / panics / etc. ADTs typically require handling immediately, exceptions are the opposite of that.