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