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

"Exceptions should be exceptional" gets to the heart of the problem with the entire concept of Exceptions for non-trivial pieces of software where there's more than a single programmer maintaining the complete system.

Now the library programmer has to guess whether when you - the application programmer try to Wibble a Foozle - will have ensured all the Foozles can be Wibbled, and so not being able to Wibble the Foozle is an exceptional condition, or whether you want to just try to Wibble every Foozle and get an error return if it can't be Wibbled...

One option is for every such condition you bifurcate the API. Instead of three types with a total of eight methods, maybe there are six conditions for two of those methods, and so now it is three types with over 100 methods... ouch. Good bye documentation and product quality.



So - exceptions are for invariant violations? I'm essentially trying to work out what it is that makes something "exceptional"


Well, this obviously depends on a given programming language/culture, but in my mind I would say in case of parsing a string to an int it is an expected case that it could fail, so I would model it as a Return type of an Int or a ParsingError, or something like that.

Meanwhile, for a function doing numerous file copies and network calls I would throw an exception, as the number of possible failure cases are almost limitless. (Like you surely not want to have an ADT that models FileSystemFullErrors and whatnot).

It so happens that in this particular example one is pure and the other is side-effecting, but I'm not convinced that's a hard rule here.


In a good effect system exceptions as effects are isomorphic to error conditions as data, so the choice comes down to what is more ergonomic for your use case, just like the choice between these three isomorphic functions should is down to ergonomics:

    frob1 :: Foo -> Bar -> R

    frob2 :: (Foo, Bar) -> R

    frob3 :: FooBar -> R
    data FooBar = FooBar { foo :: Foo, bar :: Bar }




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

Search: