1 comment

[ 3.9 ms ] story [ 13.9 ms ] thread
I think that a lot of the heat in the debate between different error handling strategies, and whether Exceptions, functional return types, or whatever are the best way, boils down to that there are very, very different requirements.

In some sectors and domains, it is not a problem if a program fails and crashes. And it is also not a problem if a change in error handling makes an internal library backwards-incompatible (*). In such environments, errors are not costly, and it is more important to quickly write code, than that it is always correct. This is even more valid in distributed computing environments which have redundancy.

In other domains, a crash could be deadly (like in an autonomous car) or could cost millions of dollars (like with the Ariane rocket) - and backwards-incompatible changes in libraries might be not tolerable neither (for example, in industrial automation, where core libraries are used for 20+ years).

(*) One point to consider which might not be obvious to most people: When extending a function, which has, say, an enumeration as one argument, it is always possible to extend it by adding new enumeration values to its input parameters, just like one can add keyword arguments with a default value. This modification is always backwards compatible.

But backwards compatibility breaks if one adds enumeration values, or new kinds of errors, or new Exception types to the *output parameters* of a function - because the code of its clients must now be modified to handle all possible cases. If one takes semantic versioning seriously, this is a breaking change. And one can argue that in a statically-typed language used for safety-critical systems, the compiler should always catch that.