Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The examples in that article (CreditCardExpiredException, SuspiciousActivityException, CardTypeNotSupportedException) show why no other languages follow Java's concept of checked exceptions. Those are examples of business logic or control flow being done by exceptions, which has been, in my experience, considered an anti-pattern for a very long time.

Other languages use union types, enums, or other type system constructs to represent operations which may have multiple possible outcomes. You're correct that these languages don't support business logic exceptions, but that also isn't an acceptable practice outside of Java.



> acceptable practice outside of Java.

What is the acceptable practice outside of Java?

Do you prefer to check for errors after every function call? That's what you had in C language, and the problem is that the logic gets buried inside all the error checking, and that makes code hard to read (and write).


The general answer is "represent it in the type system". That's typically via discriminated unions like Rust's Result, or something which emulates it (such as OneOf or Dunet for C#, although it will be a native part of the language soon).

Pattern matching, nullable types, and the Try* method conventions are also ways of representing the potential for failure explicitly.


Checked exceptions are represented in the type system. There is fundamentally no difference between these two:

    A b() throws C
    fn b() -> Result<A, C>

    A a = try {
        b()
    } catch (C c) {
        new A()
    }

    val a = b() match {
        Ok(a) => a
        Failure(c) => A()
    }




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: