9

It is a widely held position that checked exceptions as implemented in Java are a bad idea. If you mark a method as throwing, calling code has to either catch the exception, or be marked as throwing, too. For this reason, it is said that exception specifications are contagious. Consequently, they are being removed from C++ (with exception of noexcept).

I wonder if you could implement a different kind of checked exceptions. Instead of "Caller must catch this", they would mean "I will only ever throw this".

The calling scope will not have to be changed at all. It is helps me as a writer of the called function to understand what I will possibly throw - if I decide to add an annotation. It would also allow the possible exceptions to be shown during code completion. I could imagine special fatal exceptions will always be allowed, like OutOfMemoryException, or Python's KeyboardInterrupt.

For example (pseudocode):

// simple case (could actually be inferred)
string lookupString(string key) throws only KeyError {
    return m_map[key];
}

// complex failing example
string readFromFile(string filename) throws IndexError {
    File f = File.Open(filename);
    return f.readline();
}
// -> Compilation error:
// File.Open may cause IOError, but readFromFile guarantees to only throw IndexError
// (optional:)
// readFromFile suggests it will throw IndexError,
// but no operation in it may possibly throw IndexError.

In case you give no specification, I would suggest to allow any exception (throw Throwable). I imagine adding this feature to an existing language, and this would be the only backwards-compatible option. For a new language, you think about a different default.

To deal with legacy code (in an external library), there could be a way to tell the compiler that a certain function or block of code only can ever throw certain exceptions. Conceptually a bit like unsafe in C#:

I swear throws only ParseError {
    return JSON.parse(json);
}

I am not aware of any language that implements this weaker kind of checked exceptions. It seems to me they would have a lot of benefits, but without the drawbacks of Java's checked exceptions. Are there any reasons that this idea wouldn't work? Has any language successfully implemented this, or tried and failed?

(Note, please do not read this as a question looking for a language recommendation and then close it. This is a question about language design, I would like to understand the benefits and drawbacks of this approach better. Possible answers I could imagine would be: "Yes, this has been attempted in language XY, but doesn't work very well because of interplay with generics." or "No, this has never been implemented, but it is a great idea. Because of <language-theoretic argument>, this can be implemented in a sound type system. See this work of Foobar for more information.")

22
  • 1
    I'm still missing part of the proposal. What would be the semantics of a procedure in your hypothetical language that doesn't carry any specifications? May 29 '17 at 12:28
  • 2
    I agree with @KilianFoth: as soon as a method without throws is used the callee must either be nothrow/noexcept or the caller must be declared throws Throwable. I imagine this results in a great percentage of the codebase being declared as throws Throwable with junior/mid-level programmers; and that is effectively equal to unchecked exceptions.
    – marstato
    May 29 '17 at 12:37
  • 1
    @Newtopian you can already declare multiple types of checked exceptions per method in Java (for example), so I don't see that as a problem. May 29 '17 at 14:05
  • 1
    @shawnhcorey: Well, there are many different attitudes towards exceptions. But I share the worry about unrestricted exceptions "leaking" out. That is exactly the motivation behind this question: You'd add a keyword to a scope, and the compiler makes sure you can only throw approved exceptions, if any, from out of the scope.
    – jdm
    Jun 26 '17 at 12:35
  • 1
    Just throwing my 2c in: I used to be a Java developer. No more, but the one thing I miss most is checked exceptions. The way they forced me to handle bad paths. Alternative approaches that come to mind that come close are: the variant type (à la ML, or did it originate in Algol?), and (checked) multiple value return as in Go.
    – ᅙᄉᅙ
    May 1 '19 at 7:25
0

Has been done in Vala.

The caveat is that not handling the exceptions in code is a compile-time warning, the idea being that one of the main issues with java checked exceptions is that when prototyping, people tend to catch and ignore the exceptions rather than considering proper error handling. If the error does occur at runtime and has not been handled in code, the default handling logic in Vala is to immediately exit.

3
  • I think this is not the same though. The compiler warns about ignored exceptions (errors). But there is not a way to say "dear compiler please make sure that this function cannot leak a NullPointerException". (I don't know if NPEs are even a thing in Vala, but that's just an example.)
    – jdm
    Jun 10 '21 at 16:36
  • The default in Vala is that no exceptions are thrown by a function. If a function has no throws ... clause, then it will never throw an exception. If any error does occur, whether it's a null dereference, an unhandled exception, or something else the program will be terminated.
    – rhellen
    Jun 11 '21 at 12:17
  • Right, but what I suggested is a super-strict function where the compiler checks that null dereferences, unhandled exceptions etc. can never occur. (If you want to do more than simple calculations or call other super-strict functions, you could probably mark your code as safe manually.) Termination in case of a bug is exactly what I want to avoid. I'd like to catch these corner cases at compile time.
    – jdm
    Jun 12 '21 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.