On Friday, 3 October 2014 at 17:40:43 UTC, Sean Kelly wrote:
Setting aside exceptions for the moment, one thing I've
realized about errors is that in most cases, an API has no idea
how important its proper function is to the application writer.
If a programmer passes out of range arguments to a
mathematical function, his logic may be faulty, but *we have no
idea what this means to him*. The confusion about whether the
parameters to a library constitute user input is ultimately the
result of this exact problem--since we have no idea of the
importance of our library in each application, we cannot
dictate how the application should react to failures within the
library.
Yes, I agree. The exceptions are serious hardware instability
issues. Or serious errors such as a garbage collector going
bananas with no possibility of ever reclaiming any lost memory.
Those are not application level concerns. Those are kernel or
foundational runtime concerns.
I don't want my website to tank just because some library author
wrote code that is incapable of dealing with 29th of February in
a date conversion. I don't want the website to tank because a
validator throws a type related error. I want the validation to
fail, but not the program. The failure should be local to what
you are calling into.
The conversion from a local failure to a fatal error can only be
done by the application in most cases.
A contract has preconditions and postconditions to validate
different types of errors. Preconditions validate user input
(caller error), and postconditions validate resulting state
(callee error).
Preconditions establish what input the postconditions are
guaranteed to hold for. They don't really validate.
Preconditions say this: if you call me with other values than the
ones in the precondition you may or may not get what you want, it
is not my responsibility.
A precondition error suggests a logic error in the application,
and a postcondition error suggests a logic error in the
function.
I'd rather say:
1. If you call into a function breaking the precondition, then
the calling module is responsible for any errors that may occur
later on. (or rather the contractor that wrote it)
2. If the postcondition fails for input that satisfies the
precondition then the called module is responsible. (or rather
the contractor that wrote it)
The function writer is in the best position to know the
implications of a postcondition failure, but has no idea what
the implications of a precondition failure might be.
If the modules are isolated then the system architect can define
which modules are critical and which are not. So he or she can
decide whether the module should continue, be turned off, logged
for manual correction at later stage, reset or if the whole
system should enter some kind of emergency mode.
it's reasonable to assert that not only the type of contract
error is important to know what to fix, but also to know how to
react to the problem.
Yes, and maybe even know which contractor should be called to fix
the problem.
But contract violations are something different and I believe
they deserve their own category.
The support for contracts in D is not really meaningful IMO. It
is basically just regular asserts with syntax dressing.
How does this sound? It's only the beginnings of an idea so
far, but I think it's on the right track towards drawing
meaningful distinctions between error conditions in D.
I like where you are going, but think about this:
Is infinite recursion a logic error?
It should not be considered to be, because you can solve a
problem using N strategies concurrently and choose the one that
returns a valid result first.
Hence logic errors are not fatal errors until the application
code says so.
It makes a lot of sense to cut down on the amount of code you
have to write and let runtime errors happen, then catch them and
swallow them. It makes sense to just swallow errors like typing
issues if they should not occur for a result you want to use.
You simply turn the "logic error" into a "cannot compute this"
result if that is suitable for the application. And the
programming language should not make this hard.