3 ms·
What about: NullPointerException? ArrayIndexOutOfBoundsException? IllegalArgumentException? UnsupportedEncodingException?
by invalidname 3y ago
What about: NullPointerException? ArrayIndexOutOfBoundsException? IllegalArgumentException? UnsupportedEncodingException?
- naasking 3y agoWhat about them? If your language semantics are pervaded by exceptions, that kinda suggests your language sucks. If you're unlucky enough to find yourself in this situation, then make exception contracts simple to express and propagate.
- invalidname 3y agoThey aren't simple to express and propagate? What's so hard about declaring throws?
- naasking 3y agoYou have to think about exception polymorphism. If you don't have exception inference, you also have to think about manually propagating exception contracts. Declaring it once is not a big deal, doing it over and over again is super annoying.
- invalidname 3y agoThat's great, think about it... Let's say I have a Collection and want to do IO within that collection... If IOException was a runtime exception I could just write that code without handling it and an unsuspecting user of my new IOCollection would suddenly get an IOException. That means I need to explicitly deal with it in my class and can't add a serious exception to the behavior of the class. Yes, it can still throw a runtime exception which is why the separation of the two is so important. OTOH we have InputStream and OutputStream. Both throw an IOException for all their methods. So if I have one of them I should always handle the exception which is always the right thing to do... But you might say, wait... What if I have a theoretical InputStream that will never throw an IOException? Don't fret, we have that. It's called a ByteArrayInputStream and works roughly like this: ByteArrayInputStream bos = new ByteArrayInputStream(new byte[100]); int value = bos.read(); Notice I didn't use try and catch. Why? Because neither the constructor nor the read method throw an IOException which is legal in Javas polymorphism implementation. However, the following code won't compile without a catch exactly because I need to handle IOException for the generic case: InputStream bos = new ByteArrayInputStream(new byte[100]); int value = bos.read();
- MrJohz 3y agoNull pointer exceptions shouldn't exist in the first place, they're fairly trivial to avoid. Index out of bounds can be similarly avoided, although the cost in terms of economics is a lot steeper. I like Rust's strategy of providing a checked and an unchecked indexing mechanism, where the unchecked indexing mechanism typically crashes the program rather than just throwing an exception. Illegal arguments can often be avoided in the first place with sensible types (although, like null pointer exceptions, this typically requires some language support), and unsupported encodings should be rare assuming widespread UTF-8. So yes, I agree, those should all be very rare exceptions to find in a function signature.
- invalidname 3y agoNotice that parent comment was directed to a person who has the opinion of "everything should be a checked exception"... Not towards you. Crashing the program isn't an option for a lot of applications. All those exceptions give me a runtime stack that I can log and an error that's very easy to fix quickly. The first 3 are runtime exceptions which means you won't know about them and don't need to write defensive code. I love rust and its compile time checks. Checked exceptions are very similar to the concepts in rust, check as much as possible during compilation. However, this makes rust code non-trivial for some dynamic behaviors and sophisticated object graphs. There's a balance that we usually choose based on a languages target demographic. Rust is great for system programming, Java is great for enterprise programming. Both are very different domains with very different needs. The discussion about null is a huge one and I'm already spending way too much time in HN comments. Forgive me if I don't open that damn can of worms ;-)
- MrJohz 3y agoI think almost everything should be a checked exception, with some possible exceptions (haha) being things like out-of-memory exceptions (although even then, with a good type system, I can imagine them optionally throwing checked exceptions). So it's definitely written at me! Rust is not the only language that handles these sorts of issues, and it's not the only way of doing that. OCaml also very neatly avoids most of these problems (again, indexing can optionally be checked), although it also includes exceptions on top of that. Even Typescript can be written in a style where exceptions, although interfacing with third-party code is a lot more difficult then. You can even configure the Typescript compiler to enforce checked indexing and prevent index-out-of-bounds errors. The point is that there is nothing fundamental about these exceptions, other than that many languages have been designed with the assumption that they must be present and generally possible. But there's no reason to keep with that assumption, and we can write good code - and even good enterprise code, as demonstrated by Typescript - without those assumptions. I find it disappointing that we expect so little from our tools that we tolerate these sorts of problems.
- bsder 3y agoOne of these things is not like the others ... The first 3 need to terminate your thread because something is irretrievably incorrect. The only sane thing to do is stop. "UnsupportedEncodingException" has lots of things you can do to recover. You can try different encodings. You can request retry of someting. You can check a CRC for corruption. etc. So, the first 3 really shouldn't litter your code. The final one probably should.
- invalidname 3y agoFinally a person who knows Java ;-) For other readers the first 3 are all runtime exceptions and the last one is a checked exception that a lot of people complain about... I think the last one is an example of why people hate checked exceptions and the solution to this was to create newer APIs that focus on UTF-8 that just don't throw that exception.
- bsder 3y agoWhy is "UnsupportedEncodingException" an issue? It should throw only on creation and then never be an issue from that point forward, no? If it's throwing everywhere then, as you point out, that is an API problem rather than a problem with exceptions, themselves.
- invalidname 3y agoYes. It's 100% an API problem...