6 ms·
Right. They don't just "encourage" developers to consider error paths, they "force" them to do so. The concept of checked exceptions is very sound, as is the
by hota_mazi 6y ago
Right.
They don't just "encourage" developers to consider error paths, they "force" them to do so.
The concept of checked exceptions is very sound, as is the more general concept of compiler enforced error checking. Very, very few languages have that (only Java and Kotlin in the mainstream league).
Languages with a solid implementation of algebraic data types offer a good first step in that direction but they still require users to manually bubble and compose monadic values, which introduces an unnecessary, and sometimes intractable, level of obfuscation and boiler plate.
All other languages provide weaker approaches to this concept that are library enforced, not language enforced, and therefore more prone to being overlooked since they require discipline from the developer.
- augusto-moura 6y agoYou are not forced per se, and can have the same level of obsfucation. It's pretty common to find code ignoring exceptions or wrapping them in RuntimeExceptions, like: try {} catch (Exception e) { throw new RuntimeException(e); } Also not doing nothing, or the famous catch and log
- mcguire 6y agoOnce upon a time, I worked on a C++ project with another, experienced developer who kept commenting out -Wall from the Makefiles with the comment, "Nobody has time for that."
- staticassertion 6y agoYou aren't forced to handle it well, you are forced to handle it.
- ragnese 6y agoYou aren't forced to write your happy path code well, either. What's your point?
- dllthomas 6y agoThe point seemed to be that checked exceptions are a bit of a help, whereas you seem to be responding to an implied claim that they aren't helpful. I think that's why you're being downvoted.
- ragnese 6y agoPerhaps. I definitely read it as them saying checked exceptions aren't helpful because you can still handle the errors poorly. But I can see how I might have misinterpreted the intent.
- staticassertion 6y agoI suppose I wasn't clear. You did misinterpret what I said, I intended to convey the exact opposite.
- zmmmmm 6y agoAt which point it's super easy to identify in code review and slap the developer on the wrist. I find these arguments that posit incompetent / ignorant developers as a hurdle a bit strange. If they are going to incompetently handle errors wrong when explicitly forced to handle them I can't even imagine how poor their code will be without any assistance from the compiler, and it seems awful to think that you will have no way to identify such poor handling on review - you're going to have to look up every function they call and check if it can return an error or not manually.
- Groxx 6y agoi.e. Go. Go can make sure you are aware that an error exists (often. linters do pretty good here too), but it does next to nothing to help you handle it correctly. From personal experience: yes, little to no compiler help on errors takes an enormous amount of effort by both authors and reviewers (and future readers) to ensure correct handling. The vast majority of the time it's just `if err != nil { return err }`, which is very frequently sub-optimal. But without knowing the call in complete detail, you can't judge if that's true or not... and it may have changed since you last saw it. IDEs help that kind of "is this optimal/correct" question quite a lot, but they can't verify it either. It's question-marks all the way down, unless you fully know all the code you call, which is often infeasible.
- quantified 6y agoThe dev may need to. If you are implementing an interface method and the signature does not include the exception, it must be wrapped in the implementation. You’d like this not to be the case, but it’s better than trying to rewrite major dependencies. I hope they can find a more specific RuntimeException subclass to throw, but that’s a relatively minor quibble. I’d like to suggest a different POV for your comment on code review. Every method can throw exceptions, that’s life with the JVM. You don’t declare IllegalArgumentException, ArrayOutOfBoundsException, NoSuchElementException, etc. Yet your code needs to deal with it and usually does nothing because it means the element doesn’t make it into a collection, the rest of the object doesn’t get constructed, etc. Avoiding raw RTE, and instead using an RTE subclass that conveys the information you care about works fine. Code review avoids raw RTE, and all places that might care about IO exception causes etc. can process the caused-by of the wrappers. In what kind of code has this technique been an actual problem? I agree standards and techniques need to be rigorously applied.
- hota_mazi 6y agoYou are still forced to deal with it. In your example, the developer just chose to write crappy code, and there's no defense against that.
- trefil 6y agoNot sure if Rust counts as mainstream by your metric, but it does have compiler enforced error handling in the form of the Result sum type.
- ragnese 6y agoKotlin has no mechanism to force error handling. You may suggest that we use sealed classes as return values and match on them, which is okay-ish, but suffers from two big issues: 1. You are not forced to use the result, so if you call a function for its side effects, the compiler will not warn you that you should unwrap the value. Rust and Swift do not have this issue. 2. This is extremely tedious, as you mention. But it's specific to Kotlin and not generally true as you later suggest. Haskell had monad comprehension (do notation), Scala has the same thing, Rust has the ? operator. Also, regarding Kotlin; no library, nor the standard library, does anything other than throw unchecked exceptions on all kinds of failures. Kotlin is a step backwards, IMO. Also PHP has checked exceptions, like Java.
- hota_mazi 6y ago> Kotlin has no mechanism to force error handling. I was referring to nullability support, which is similar to Option/Maybe, except that it's enforced by the compiler. This is pretty unique to Kotlin at the moment (honorable mention to Ceylon which offered similar support).
- iainmerrick 6y agoUnique to Kotlin? Don’t Swift and TypeScript have this feature too? Maybe it’s just the languages I’ve been working with this recently, but I think of this as something that’s breaking into the mainstream as language designers are starting to agree that it’s a good idea.
- ragnese 6y agoI like Kotlin's null most of the time, but I actually prefer Option still because every once in a while I need to nest them. You can nest Option, but not null.
- valenterry 6y agoI think you should look into some more programming languages before you claim that this is unique to Kotlin. ;)
- 6y ago
- TazeTSchnitzel 6y ago> compiler enforced error checking. Very, very few languages have that __attribute__ ((warn_unused_result)) in C/C++ with GCC and Clang is great.
- vinkelhake 6y agoAnd standardized as [[nodiscard]] in C++17.
- MaxBarraclough 6y agoInteresting, thanks. https://en.cppreference.com/w/cpp/language/attributes/nodiscard https://en.cppreference.com/w/cpp/language/attributes/nodisc...
- dllthomas 6y agoI conjecture that much of the legitimate pain from checked exceptions in Java were because the language to talk about exceptions was so limited. For instance, consider fold or map functions. There was no way of saying "this might throw anything that might throw", so the only option was "this won't throw anything and that cannot throw anything" or "this might throw anything". Without the necessary flexibility, developers aren't "forced" to consider only error paths but also manifold impossible paths that aren't easily distinguished from legitimate error paths.
- amw-zero 6y agoAvoiding the “boilerplate” of error handling means that you have implicitly coupled code now. Exceptions make local reasoning not possible. I guess you may want that in a small minority of cases, but I don’t understand the benefit they give you overall. It’s just a shortcut and a hack, and I’d rather see explicit control flow 100% of the time.