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

Reply via email to