So in a relatively famous blog post, Eric Lippert categorizes exceptions as lethal, vexing, bone-headed, and exogenous. He defines vexing exceptions as ones created by unfortunate design decisions and gives the example of
Int32.parse from C#. Attempting to parse a user-input string as an integer may well fail, and is in no way exceptional: forcing the programmer to wrap this call in a try/catch block is gratuitous, hence the addition of
He then goes on to define exogenous exceptions as exceptions beyond one's
control using file IO as an example. But that (at least in modern languages) seems like a design choice: a file opening operation could return filepointer/filereader_object/read_stream on success or null (or some other sentinel value) on failure, with a requisite conditional check afterwards. Better yet, one could return a
Maybe of a read_stream (or an
Either), and modern functional languages more or less do just that.
Is there an advantage to throwing an exception if a file isn't found vs one of the other options I outlined? Or is this just an unfortunate/legacy design decision?