enforce()?

bearophile bearophileHUGS at lycos.com
Mon Jun 21 11:41:14 PDT 2010


Sean Kelly:

>First, what if a library eats its own dogfood?  If my library provides a public method to spawn threads and the library itself uses threads internally then I have two different methods of checking the integrity of my own library, each possibly throwing different exceptions (enforce throws Exception while assert throws AssertError).<

I think that Design by contract, to be useful, needs to be embraced. You need to trust it and use it everywhere. Now I use DbC quite often in my D code and I appreciate it. The DbC feature I miss mostly is the "old" (view of the original input data).


>For example, I created an AVL tree a while back that verified that the tree was still properly balanced after every API call.  This was great from a code verification standpoint, but the check completely violated the complexity guarantees and ultimately checked something that could have been proven to a reasonable degree of confidence through code reviews and unit testing.  Should checks like this be enabled automatically when DbC is turned on?  Should there be different levels of DbC?  In some respects I feel like there's a difference between in/out contracts and invariants, but even that doesn't seem completely right.  Thoughts?<

Using Design by Contract is not easy, you need to train yourself to use it well. A problem is that DbC is uncommon, only Eiffel and few other languages use it seriously, so lot of D users have to learn DbC on D itself.

I face your problem putting inside the contracts code that doesn't change the complexity of the code it guards (so for example if the code is O(n^2) I don't add contracts that perform O(n^3) computations).

Then where it's useful I add stronger tests (that can be slower) inside debug{}. You can see it here too:
http://www.digitalmars.com/pnews/read.php?server=news.digitalmars.com&group=digitalmars.D&artnum=109395&header

Inside the invariant there is O(1) test code, and it also contains inside a debug{} O(n) test code (that is .

In debug mode I want to test the code very well, while in normal nonrelease mode I can accept less stringent tests that make the code usable.

Unittests and DbC (and integration tests, functional tests, smoke tests, etc) are both useful, they do different things :-) For example an unittest can tell me a function is wrong, but a loop invariant can tell me where the bug is and when it happens inside the function :-)

Bye,
bearophile


More information about the Digitalmars-d mailing list