Is D still alive?

bearophile bearophileHUGS at lycos.com
Fri Jan 28 03:36:15 PST 2011


Jonathan M Davis:

> I generally end up using unit tests to verify that stuff works correctly and then 
> throw exceptions on bad input. So while I like having DbC built in, I don't end 
> up using it all that much. It's prim,arily invariant that I end up using though, 
> and that's harder to do inside of the member functions.

I think the problem here is that you are not using your D tools well enough yet:
- Preconditions allow you to save some tests in your unittests, because you have less need to test many input boundary conditions.
- Postconditions are useful to save some code to test the correctness of the results inside your unittests. You still need to put many tricky but correct input conditions inside your unittests, but then the postcondition will test that the outputs are inside the class of the correct outputs, and you will need less unittest code to test that the results are exactly the expected ones in some important situations.
- The missing "old" feature once somehow implemented allows to remove some other unittests, because you don't need a unittest any more to test the output is generally correct given a certain class of input.
- Class/struct invariants do something unittests have a hard time doing: testing the internal consistency of the class/struct data structures in all moments, and catching an inconsistency as soon as possible, this allows to catch bugs very soon, even before results reach the unittesting code. So their work is not much duplicated by unit testing.
- Loop invariants can't be replaced well enough by unittests. Again, they help you find bugs very early, often no more than few lines of code later of where the bug is. Unittests are not much able to do this.
- Currently you can't use invariants in some situations because of some DMD bugs.
- You must look a bit forward too. If D will have some success then some person will try to write some tool to test some contracts at compile time. Compile-time testing of contracts is useful because it's the opposite of a sampling: it's like an extension of the type system, it allows you to be sure of something for all possible cases.

Unit tests are useful as a sampling mean, they allow you to assert your function does exactly as expected for some specific input-output pairs. DbC doesn't perform a sampling, it tests more general properties about your inputs or outputs (and if you have some kind of implementation of the "old" feature, also general properties between inputs and their outputs), so DbC testing is wider but less deep and less specific than unit testing.

Generally with unittesting you can't be sure to have covered all interesting input-output cases (code coverage tools here help but don't solve the problem. Fuzzytesting tools are able to cover other cases), while with DbC you can't be sure your general rules about correct inputs, correct outputs (or even general rules about what a correct input-output pair is) are accurate enough to catch all bad situations and computations.

So generally DbC and unittests are better for different purposes, using them both you are able to complement each other weak points, and to improve your D coding.

I also suggest to try to write contracts first and code later, sometimes it helps.

Bye,
bearophile


More information about the Digitalmars-d mailing list