Live data from Hacker News

Why checked exceptions failed

borretti.me

221–230 of 318 posts

Re: Why checked exceptions failed

#221

Earlier quoted context omitted.

You are very confused... "strong" in strong typing doesn't mean you have to write much or at all. Actually, it doesn't mean anything really. But, let's say, Haskell is probably at least as "strongly typed" as Java -- at least that's how most people understand that wording. And you don't have to write types in Haskell at all. It will be a nightmare (as if Haskell can be anything else, but even by the very low Haskell…

Type inferencing can get you in trouble quickly. Consider this code: var fireable = someMethod(); firable.fire(); The programmer intended this code to fire an employee. Let's say this code is in a military application, and another programmer modified the someMethod() function to return a missile. As long as the missile object has a fire() method this code will compile just fine... and do something the code didn't int…

someMethod() could return an implementation of Employee that overloads the fire method to dispatch missiles.

The point being, someMethod is doing some job that you want it to do. It is incredibly unlikely to simultaneously start doing a completely different job, while also returning something of the same shape.

Re: Why checked exceptions failed

#222

Earlier quoted context omitted.

We have it in Java too. For us it's try-with-resources and has nothing to do with checked exceptions. Checked exceptions remind you that you need to wrap the code and need to take that into account. They also force you to declare that an exception is thrown if you don't want to handle it in the current method. That's important as the signature of the method carries an important failure that can't be dismissed and is…

> important failure that can't be dismissed But importance of the failure is determined completely by the program, not the library. Grep fails to open a file for reading -> message the user and exit Nuclear reactor controller fails to read important a file -> initiate reactor shutdown or something. If file read is critical, you have to handle failure no matter what the interface is. Because you know that disk can fai…

> But importance of the failure is determined completely by the program, not the library.

Exactly. I think this is the real crux about what's wrong with checked exceptions. It puts the responsibility to decide what exceptions are important on the library, where it doesn't belong. Only the user of the library knows that.

Re: Why checked exceptions failed

#223

Earlier quoted context omitted.

Checked exceptions should be the default, exceptions should just be rare. They are overused in almost all languages.

Agreed. Too often exceptions end up driving normal control flow, when the should just be...exceptions.

You must have a real panic when you see a sign saying “No parking except weekends.” Weekends happen all the time!

Re: Why checked exceptions failed

#224

Earlier quoted context omitted.

This is one of the main reasons why I personally try to avoid exceptions and instead encode failure into the type system. For example, returning a Result rather than just a 't. (You can refine the type further). Altough, in most languages that approach results in a lot of boilerplate. In F# it works quite well, though.

How is this different in practice? Checked exceptions are simply "syntactic sugar" for error types (exception objects with a few special handlers to return them and receive them). You can write almost exactly the same code with your Result by ignoring the error until the point you would catch it with exceptions. The only difference is that exceptions bubble up if unhandled, which requires a generic catch to match cod…

> How is this different in practice?

It is quite a bit more explicit in that something can have an error and in what ways it can error (if you enrich the type in that way), while still being ergonomical. And it reserves exceptions for the truly unexpected/exceptional cases.

Re: Why checked exceptions failed

#225
post #151
post #91

Earlier quoted context omitted.

No value judgement here, I don't think, at least not from me (though of course my values inform every opinion I have, including this one). I simply claim that every path is equivalent, and all must be considered. I claim there is no so-called "happy path" - a term I reject - nor do "errors" really exist. There is one case where the socket send succeeded, and another where it failed. There is one case where the file n…

The correct behavior for not just the vast majority of these conditions but virtually all of them is the same: propagate the error. You aren't going to sit around and try to "recover" from failing to send a packet or encode a filename: you just report it to higher level code. There might be something you can do at a higher level--such as reconnecting or using a different server from a load balancing list--but at that…

My opinion was informed by writing the higher levels rather than the lower ones! Yes, the code absolutely is going to try to recover from sending a packet, because it was sending that in service of some larger goal that now needs unwinding partway through. And, yes, it is going to try to reconnect, or use a different server - or whatever.

The thing it really doesn't want to do is punt the issue on to some higher level. Because there isn't one.

But, equally, you don't want to be swallowing interesting problems that genuinely indicate actual bugs. Those, you do want to pass on (and due to the lack of any higher level, your process will be killed, and some mechanism will spring into action to produce a report).

Re: Why checked exceptions failed

#226

Earlier quoted context omitted.

Agreed. Too often exceptions end up driving normal control flow, when the should just be...exceptions.

You must have a real panic when you see a sign saying “No parking except weekends.” Weekends happen all the time!

So if you write code that handles dates you'd throw NotWeekendException to notify the caller that it's not weekend?

Exceptions should be for exceptions, not control flow.

Re: Why checked exceptions failed

#227

Earlier quoted context omitted.

> important failure that can't be dismissed But importance of the failure is determined completely by the program, not the library. Grep fails to open a file for reading -> message the user and exit Nuclear reactor controller fails to read important a file -> initiate reactor shutdown or something. If file read is critical, you have to handle failure no matter what the interface is. Because you know that disk can fai…

> But importance of the failure is determined completely by the program, not the library. Exactly. I think this is the real crux about what's wrong with checked exceptions. It puts the responsibility to decide what exceptions are important on the library, where it doesn't belong. Only the user of the library knows that.

Isn't it exactly the opposite? Checked exceptions are for libraries to declare "exceptions" they can't handle themselves. You, the user of the library, have to deal with them (or declare them checked yourself¹).

I'm not a friend of checked exceptions myself, but I still think it's the opposite.

¹ which leads to the real issue with checked exceptions: they propagate through dependencies, if one nested dependency adds another checked exception, all dependencies have to add the exception or handle it themselves.

Re: Why checked exceptions failed

#228

Earlier quoted context omitted.

Checked exceptions should be the default, exceptions should just be rare. They are overused in almost all languages.

What about: NullPointerException? ArrayIndexOutOfBoundsException? IllegalArgumentException? UnsupportedEncodingException?

One 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.

Re: Why checked exceptions failed

#229
post #220

> Can I specify that implementations of foo can throw no, some, or all exceptions? What would it even mean to write something like throws *? Analogously, if I have a function that takes a method as an argument, like a callback, how do I specify what set of exceptions in can throw? Can I have generic “exception set parameters”? > Concretely, checked exceptions in Java failed because Java lacks “throwingness polymorphi…

The author's point about the orthogonality of exceptions to values and types still stands; try creating a class like

    abstract class GenericException extends Exception {
        R reason();
    }
As it is, Exception is a "special" type that isn't allowed to be used like normal Java types, because Java generics are a leaky abstraction introduced after checked exceptions, and the JVM cannot deal with type erasure in catch blocks.

Re: Why checked exceptions failed

#230

Earlier quoted context omitted.

Type inferencing can get you in trouble quickly. Consider this code: var fireable = someMethod(); firable.fire(); The programmer intended this code to fire an employee. Let's say this code is in a military application, and another programmer modified the someMethod() function to return a missile. As long as the missile object has a fire() method this code will compile just fine... and do something the code didn't int…

someMethod() could return an implementation of Employee that overloads the fire method to dispatch missiles. The point being, someMethod is doing some job that you want it to do. It is incredibly unlikely to simultaneously start doing a completely different job, while also returning something of the same shape.

> an implementation of Employee that overloads the fire method to dispatch missiles

If you intentionally break it, that's on you.

> It is incredibly unlikely to simultaneously start doing a completely different job, while also returning something of the same shape.

But it doesn't need to return something of the same shape! The shape is not being checked. All the compiler checks is for the existence of a single method of the same name. You call that type checking?

Post reply on HN