
Henning Thielemann escribió:
A library function that reads a config file may declare to be able to throw the exception "File not found", or it may introduce a new exception "Could not read Config file" with an extra field for the reason, why the file could not be read. This way you can construct a call stack that helps the user (and not the programmer). Then the message reported to the user might be:
Program could not be started, because Config file could not be read because Config file does not exist in dir0, dir1, dir2
but the exception handler may also decide to use a default configuration instead or ask the user, how to proceed.
Anyway, such a call stack for the user requires different information than a call stack for programmer for debugging.
The point here being? My point has been "As programming errors are something common lets at least make them easy to solve". If you make such a fancy stack the programmer is still clueless about where the unhandled exception was generated and can't solve it. There is also another important point here which is error recovery, it's not unusual to see on servers and other high availability programs a last barrier which would show info on the error and then restart/resume the server as if nothing has happened. Following your definition, now we have exceptions, not errors, as they are expected, though they made some harm to our transaction. Henning Thielemann escribió:
The case of (head []) is simple: It is a programming error, since the precondition for calling 'head' is that the argument list is non-empty. The caller of 'head' is responsible to check this. If the list comes from user input, then the program part that receives this list from the user is responsible to check for the empty list before calling 'head'. If there is no such check, this is a programming error, and it will not be possible to handle this (like an exception). Before you answer: "What about web servers?", please read on the article I have written recently to sum up the confusion about errors and exceptions:
Well I got used to going back to the previous state without crashing when I got a precondition violation due to user input. Though I assume that was asking a bit too much of Haskell. Of course crashing the whole program as default behaviour is a better way to solve the problem.