Improve "Improve Contract Syntax" DIP 1009

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sat Nov 4 06:08:22 UTC 2017


On Friday, November 03, 2017 12:34:22 Mark via Digitalmars-d wrote:
> On Friday, 3 November 2017 at 02:32:41 UTC, Jonathan M Davis
>
> wrote:
> > Pretty much the only case where out contracts work well is when
> > you have a very specific, testable condition that all results
> > must have and which does not depend on the input, and most
> > functions simply don't work that way.
> > - Jonathan M Davis
>
> Can you give an example of a function for which this doesn't work?

Um, most functions? Heck, take a really simply one like sqrt. All you have
to check in the out contract is the return value. You have no idea what was
passed in. So, how would you write an out contract verifying that you got
the correct number? If you also had access to the input, then you could do
the reverse operation by squaring the result to see if it matched the input
(assuming of course that floating point rounding errors don't make that not
work), but you don't have access to the input.

And even if you did have access to the input, some functions consume their
input without any way to save it (e.g. an input range that isn't a forward
range), and not all operations are reversible - e.g. if you have a hash
function, you can't get the original value back from it to check against
what was passed in. So, for a lot of stuff, even if you had the original
input, you would have to essentially implement the function a second time in
the out contract to verify the result, and who's to say that the
implementation in the out contract isn't just as buggy as the one in the
main function (assuming that it's even different at all)? And that's still
assuming that you had access to the input parameters in the out contract,
which you don't.

In order to have an out contract be of any use, it needs to be able to
verify something about the state of the result without having any clue what
the input was. You essentially need to be able to pass the result to a
function that says whether an arbitrary result is valid or not. Something
like sort can do that, because you know that the result is supposed to be
sorted, and that's a testable condition (albeit a condition that's not very
cheap to test), but for most functions there simply doesn't exist a test for
knowing whether the result is correct by only looking at the result.

On the other hand, if you know what output a function is supposed to have
for a given input, it's trivial to test that with a unit test. The only
thing that's worse about that is that if you could somehow test the result
in an out contract, then it's possible to test the result for every
invocation of that function instead of just testing a specific set of
inputs. So, upon occasion, an out contract may be useful, but it rarely is,
and even if it is, if your unit tests are good, they'll likely catch all of
the problems that the out contract would catch, and the out contract would
slow down every non-release build, so if the unit tests are enough to catch
the bugs, then having the out contract just needlessly slows down your
program (which may or may not matter, depending on what you do with
non-release builds, but it can matter).

So, all in all, I think that unit tests solve the problem that out contracts
are trying to solve and do it in a way that works in general, whereas out
contracts only work in specific cases. So, I don't see much point in using
them.

- Jonathan M Davis



More information about the Digitalmars-d mailing list