Live data from Hacker News

Why checked exceptions failed

borretti.me

211–220 of 318 posts

Re: Why checked exceptions failed

#211
post #5

This is a very old topic. Insights from Anders Hejlsberg: https://www.artima.com/articles/the-trouble-with-checked-exc...

Great article with a lot of pithy insights. Here's one of the core issues with checked exceptions. 2nd sentence to the last is the point.

> Anders Hejlsberg: Yeah, well, Einstein said that, "Do the simplest thing possible, but no simpler." The concern I have about checked exceptions is the handcuffs they put on programmers. You see programmers picking up new APIs that have all these throws clauses, and then you see how convoluted their code gets, and you realize the checked exceptions aren't helping them any. It is sort of these dictatorial API designers telling you how to do your exception handling. They should not be doing that.

Re: Why checked exceptions failed

#212

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 the point is that in both cases the failure needs to be handled somewhere and somehow. Surfacing the error might be a valid option, but to make the decision you need to know that the error is there in the first place.

This can be solved with good documentation, but it can also be solved in the type system. Typically, if I can get my computer to do work for me (e.g. make sure that I've handled all possible error cases) then I'm much more confident in my code, hence why I see a lot of value in a well-designed checked exceptions system.

Re: Why checked exceptions failed

#213
post #58
post #31

Earlier quoted context omitted.

I often run into the opposite problem: There are union types, but I would really like sum types (i.e. tagged unions). The common case is a data structure where I cannot guarantee that the user will not want to use Null as a value in my data structure, but I also need to represent the absence of values myself. With a sum type, my absence would be None and the user’s absence would be Some(None). With union types, I nee…

Something like String|NoAnswer|None doesn't sound too bad to me here...

Except that NoAnswer has none of the language’s (and it’s library’s) support for the built-in None. And you might run into problems when trying nest the data structure, which might be a reasonable thing for your users to do.

Re: Why checked exceptions failed

#214
post #66

I have extensive experience in C# as well as Java. It is bizarre to suggest that checked exceptions have failed. It is unchecked exceptions that have failed. It is the biggest flaw of C#, in fact. Why? As an example, I wrote some very good C# code, carefully tested it, made it work flawlessly, then suddenly it started crashing. What happened? Someone made a change in a function I was calling, and it started throwing…

I stopped using Java a long time ago, and so I assume the language has gotten better since then, but early on at least it felt like Java almost took pride in making the developer jump through extra hoops. Compared to many other languages, using Java just made me feel tired. Checked exceptions - a feature that seems to be a cost to the developer 100% of the time while being a benefit far less than 1% of the time - is…

Java almost took pride in making the developer jump through extra hoops

That's exactly it. A holier-than-thou stance, reprised by most comments in this post.

Checked exceptions were a PITA.

Someone has recommended to use another language if you didn't like it. Unfortunately my employer at that time had entered a partnership with Sun that prevented that :)

Another ideological prohibition: no pointers. Well, how do you assign event handlers then? People were extremely confused with anonymous classes. I got the reason instantly.

Re: Why checked exceptions failed

#215

Earlier quoted context omitted.

No. This comes from a misunderstanding of checked exceptions. Checked exceptions don't mean I need to handle the exception right now. They mean I need to either do that or declare throws. Declaring throws is fine it implicitly documents the code and enforces a similar requirement up the chain. Checked exceptions aren't the default and shouldn't be.

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.

Re: Why checked exceptions failed

#216

Earlier quoted context omitted.

No, that's not it. The same problem is true for other error-handling types, such as the "either" or "result" types. Languages without union types or a similar mechanism are unable to define the error types adhoc and force the developer to define them in advance, which is very unergonomic. But that is true in both cases. The problems with checked exceptions come on top, namely that you cannot use all the regular value…

> No, that's not it. The same problem is true for other error-handling types, such as the "either" or "result" types. Languages without union types or a similar mechanism are unable to define the error types adhoc and force the developer to define them in advance, which is very unergonomic We are saying the same thing, aren't we? But it is not only about exceptions. Other effects have the same problem and you need a…

Maybe we do and I can't read. :-)

Re: Why checked exceptions failed

#217

Earlier quoted context omitted.

This is very simplistic view of the problem. This completely glosses over modularity, ABI, performance optimizations... just to name a few. How are you going to write generic functions that take functions as arguments and re-throw the errors thrown by these functions, if you use checked exceptions? Will you require that the acceptable functions only throw exceptions that you like? -- Then your generic function is clo…

> How are you going to write generic functions that take functions as arguments and re-throw the errors thrown by these functions, if you use checked exceptions? I've actually done this with an interface type parameter used in a throws clause in Java before, but I'm not sure how it interacts with module boundaries, it's kind of verbose, and it certainly didn't seem to be common practice. But it did work: the HOF-ish…

Right, I was thinking that this is the answer to the supposedly intractable problem posed by the original article.

Just make your ExampleInterface generic -- ExampleInterface.foo() throws T.

That technique works really well, and I don’t understand why it isn’t more widely used (or at least it wasn’t when I last used Java for serious work).

Re: Why checked exceptions failed

#218

Earlier quoted context omitted.

If constructing "out" fails but one of the catch-blocks tries to use "out", what should happen?

Python is an example of a language that works like this. When the constructor throws, 'out' remains not defined, but you can just do 'out = ...' in the catch block and define one with a fallback value. So all the code after the error handing would just see a working 'out' variable. This works due to all variables being bound to the function scope, not to the code block, in Python.

In Python, sure, but I struggle to see a way to make it make sense in C++.

Re: Why checked exceptions failed

#219
post #187
post #55

Earlier quoted context omitted.

Yes, in Java’s parlance an Exception is a recoverable code path, Error is the kind that is not. E.g. a network call failing due to some IOException can be easily retried, that’s a proper error handling.

How are you supposed to recover from IllegalArgumentException or NullPointerException?

Recoverable, as a technical term. You can catch an NPE and follow it with any kind of code you wish, it will be correctly “handled” by the VM. (The semantics of course depend on the exact specifics, but returning a server 500 error and not failing the process for example in a web server is completely valid).

You can try catching an OutOfMemory Error, but it is not guaranteed that your handling code can successfully run. Hence, non-recoverable.

Re: Why checked exceptions failed

#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 polymorphism”, if you will.

I don't understand. Every "missing feature" the author asks for is, in fact, present in Java. The example below just about sums it up.

  @FunctionalInterface
  interface MyCallback {

    Y apply (X x) throws E;
    
  }
  
  class A {

     Y runCallback (MyCallback func, X x) throws E {
      return func.apply(x);
    }
    
  }
Post reply on HN