[contract] Contract Programming Library

Hi all, I am thinking to submit a library for Contract Programming (a.k.a. Design By Contract (TM) ) for C++. I have drafted some of the library documentation in Boost-like format: http://dbcpp.sourceforge.net/boost/libs/contract/doc/html/ Comments? Regards, Lorenzo

On Tue, Jan 5, 2010 at 12:54 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
Hi all,
I am thinking to submit a library for Contract Programming (a.k.a. Design By Contract (TM) ) for C++.
I have drafted some of the library documentation in Boost-like format: http://dbcpp.sourceforge.net/boost/libs/contract/doc/html/
Comments?
1. I am _very_ interested in a good DbC solution for C++. I would immediately adopt it for our in-house projects. 2. I'm not fond of the syntax - there seems to be a lot of redundancy in it. I know we're working within the limitations of C++, which may be considerable in this case, but are you open to discussion about possible different approaches? I have a few (completely undeveloped and perhaps implausible) ideas.

be considerable in this case, but are you open to discussion about possible different approaches? I have a few (completely undeveloped and perhaps implausible) ideas.
Jason: Yes, I am interested in alternative approaches (I've studied more or less all the ones I could find on the Internet). Please write me an email with your ideas and I'll consider them against the Contract Programming requirements.

Comments?
I like what I've seen so far. I also like the new name. How about my interest in such a DbC library, and would I use it? I would be interested to see how DbC can be done in C++, and how it will feel. On the other hand, I "know" that I will not use DbC for "real" projects, even so I completely acknowledge the benefits it has with respect to documentation and testing. This is because testing is too important to focus on a single "random" aspect. The test requirements of different projects are so different that in principle testing should start with an investigation of the test requirements of the individual project. I fear that DbC would give a false sense of security with respect to testing. I have less problems with the documentation part of DbC, especially since it avoids the "obsolete" problem that typically plagues documentation. Regards, Thomas

Hi Thomas, On Tue, Jan 5, 2010 at 12:56 PM, Thomas Klimpel <Thomas.Klimpel@synopsys.com> wrote:
How about my interest in such a DbC library, and would I use it? I would be interested to see how DbC can be done in C++, and how it will feel. On the other hand, I "know" that I will not use DbC for "real" projects, even so I completely acknowledge the benefits it has with respect to documentation and testing. This is because testing is too important to focus on a single "random" aspect. The test requirements of different projects are so different that in principle testing should start with an investigation of the test requirements of the individual project. I fear that DbC would give a false sense of security with respect to testing. I have less problems with the documentation part of DbC, especially since it avoids the "obsolete" problem that typically plagues documentation.
Indeed, [Ottosen2004] expresses a similar concern. I will add the "false sense of security" concern to the library documentation in the Contract Programming annex. Personally, I have used Contract Programming in a couple of real projects -- one of which, an embedded safety critical system with ~60,000 lines of C++. Regards, Lorenzo

On Wed, Jan 6, 2010 at 7:19 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
Hi Thomas,
On Tue, Jan 5, 2010 at 12:56 PM, Thomas Klimpel <Thomas.Klimpel@synopsys.com> wrote:
How about my interest in such a DbC library, and would I use it? I would be interested to see how DbC can be done in C++, and how it will feel. On the other hand, I "know" that I will not use DbC for "real" projects, even so I completely acknowledge the benefits it has with respect to documentation and testing. This is because testing is too important to focus on a single "random" aspect. The test requirements of different projects are so different that in principle testing should start with an investigation of the test requirements of the individual project. I fear that DbC would give a false sense of security with respect to testing. I have less problems with the documentation part of DbC, especially since it avoids the "obsolete" problem that typically plagues documentation.
Indeed, [Ottosen2004] expresses a similar concern. I will add the "false sense of security" concern to the library documentation in the Contract Programming annex.
Personally, I have used Contract Programming in a couple of real projects -- one of which, an embedded safety critical system with ~60,000 lines of C++.
In case others are curious, here's how I would use it in a "real project": I currently use test-driven development. The standard xUnit format for tests has quite often become horribly cumbersome and I even blogged a bit about why and my solution here: http://eraserhead.net/2009/12/write-a-test-driver-class/ My test driver classes serve two primary functions: 1. To build and inject all the dependencies so I don't up with spaghetti code, large setUp() and tearDown(), and lots of free functions in my xUnit suite class. 2. To enforce class invariants and post-conditions. (My test driver class delegates to the class under test.) It's a bit of work, and sometimes the driver class gets heavy and is difficult to understand. I use the tests as executable documentation to begin with, so if I can push "executable documentation" of pre-conditions, post-conditions, and class invariants back into the class under test, I think this would much improve readability of both the class itself and the testing code. So it's really something I'm already doing by having significant test coverage, but that this would improve on.

----- Original Message ----- From: "Lorenzo Caminiti" <lorcaminiti@gmail.com> To: <boost@lists.boost.org> Sent: Tuesday, January 05, 2010 6:54 AM Subject: [boost] [contract] Contract Programming Library
Hi all,
I am thinking to submit a library for Contract Programming (a.k.a. Design By Contract (TM) ) for C++.
I have drafted some of the library documentation in Boost-like format: http://dbcpp.sourceforge.net/boost/libs/contract/doc/html/
Comments?
Hi, I find your library very interesting and except some unavoidable preprocessor ugly (), the syntax follows quite closely the C++ proposal. Have you considered to add block invariants? Maybe you can complete the table Contract Programming Feature Comparison. If I have understood your library require the type is CopyConstructible to manage with postconditions. Have you considered to relax this constraint? I have taken the freedonm to add it to the Boost Libraries Under Construction https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction . Let me know if all the informations are right. Good work, Vicente

On Tue, Jan 5, 2010 at 11:28 AM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
----- Original Message ----- From: "Lorenzo Caminiti" <lorcaminiti@gmail.com> To: <boost@lists.boost.org> Sent: Tuesday, January 05, 2010 6:54 AM Subject: [boost] [contract] Contract Programming Library
Hi all,
I am thinking to submit a library for Contract Programming (a.k.a. Design By Contract (TM) ) for C++.
I have drafted some of the library documentation in Boost-like format: http://dbcpp.sourceforge.net/boost/libs/contract/doc/html/
Comments?
Hi,
I find your library very interesting and except some unavoidable preprocessor ugly (), the syntax follows quite closely the C++ proposal.
Have you considered to add block invariants? Maybe you can complete the table Contract Programming Feature Comparison.
If I have understood your library require the type is CopyConstructible to manage with postconditions. Have you considered to relax this constraint?
I have taken the freedonm to add it to the Boost Libraries Under Construction https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction . Let me know if all the informations are right.
For note, the Wt (C++ web toolkit) is making a Dbo sublibrary. No fancy meta-programming techniques, but it runs well and is quite lightweight. It has just been started, but it is already usable.

On Tue, Jan 5, 2010 at 7:54 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
For note, the Wt (C++ web toolkit) is making a Dbo sublibrary. No fancy meta-programming techniques, but it runs well and is quite lightweight. It has just been started, but it is already usable.
OvermindDL1, can you please provide a link to Wt DbC source, examples, documentation, etc. I would like to take a close look at it. Thanks, Lorenzo

On Thu, Jan 7, 2010 at 5:20 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Tue, Jan 5, 2010 at 7:54 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
For note, the Wt (C++ web toolkit) is making a Dbo sublibrary. No fancy meta-programming techniques, but it runs well and is quite lightweight. It has just been started, but it is already usable.
OvermindDL1, can you please provide a link to Wt DbC source, examples, documentation, etc. I would like to take a close look at it.
To the source, it uses git: http://www.webtoolkit.eu/git/wt.git For examples, there are two included in the source (pretty simple, but the example page works well so far) The documentation is pretty simple currently, mostly just doxygen in the main doc area, but the tutorial demonstrates it best: http://www.webtoolkit.eu/wt/doc/tutorial/dbo/tutorial.html The first blog post about it is: http://www.webtoolkit.eu/wt#/blog/2009/11/26/wt__dbo__an_orm__c___style/more About the only place it uses templates is the query structure to bind to a table class or something like an int if you ask for a count(*) or something. You still have to type in a lot of the SQL constructs, but all binding is done safely and it uses stored procedures a *lot*, and everything requires transactions. I still think boost could make a more db-backend agnostic version ala sqlalchemy, but they are trying to go for it. It is basically version 0.0.1 right now. It has some cool features, and they are adding more things in the git trunk as time goes by. The main problem I have, is like all of the Wt things, it is gpl2 (making it fine for web server stuff, which Wt is, but nothing for anything decent).

Hi OvermindDL1 Are you sure you posted in the right thread? There was also a database thread recently, and what you write "You still have to type in a lot of the SQL constructs..." sounds more database related than related to Design by Contract (TM). Regards, Thomas -----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of OvermindDL1 Sent: Donnerstag, 7. Januar 2010 14:15 To: boost@lists.boost.org Subject: Re: [boost] [contract] Contract Programming Library On Thu, Jan 7, 2010 at 5:20 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Tue, Jan 5, 2010 at 7:54 PM, OvermindDL1 <overminddl1@gmail.com> wrote:
For note, the Wt (C++ web toolkit) is making a Dbo sublibrary. No fancy meta-programming techniques, but it runs well and is quite lightweight. It has just been started, but it is already usable.
OvermindDL1, can you please provide a link to Wt DbC source, examples, documentation, etc. I would like to take a close look at it.
To the source, it uses git: http://www.webtoolkit.eu/git/wt.git For examples, there are two included in the source (pretty simple, but the example page works well so far) The documentation is pretty simple currently, mostly just doxygen in the main doc area, but the tutorial demonstrates it best: http://www.webtoolkit.eu/wt/doc/tutorial/dbo/tutorial.html The first blog post about it is: http://www.webtoolkit.eu/wt#/blog/2009/11/26/wt__dbo__an_orm__c___style/more About the only place it uses templates is the query structure to bind to a table class or something like an int if you ask for a count(*) or something. You still have to type in a lot of the SQL constructs, but all binding is done safely and it uses stored procedures a *lot*, and everything requires transactions. I still think boost could make a more db-backend agnostic version ala sqlalchemy, but they are trying to go for it. It is basically version 0.0.1 right now. It has some cool features, and they are adding more things in the git trunk as time goes by. The main problem I have, is like all of the Wt things, it is gpl2 (making it fine for web server stuff, which Wt is, but nothing for anything decent). _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Thu, Jan 7, 2010 at 6:20 AM, Thomas Klimpel <Thomas.Klimpel@synopsys.com> wrote:
Hi OvermindDL1
Are you sure you posted in the right thread? There was also a database thread recently, and what you write "You still have to type in a lot of the SQL constructs..." sounds more database related than related to Design by Contract (TM).
True, but I was responding to Lorenzo the second time, not sure what I was originally responding to the first time... >.>

Vicente:
Have you considered to add block invariants? Maybe you can complete the table Contract Programming Feature Comparison.
I think block invariants could be added if there was interest. Indeed, I have already implemented a class for Eiffel-like loop-contract with both invariants and variants (but I never use it in real code). In the Contract Programming proposal for the C++ standard, block invariants are interesting also because they allow for additional compiler optimization but this benefit does not apply to a library.
If I have understood your library require the type is CopyConstructible to manage with postconditions. Have you considered to relax this constraint?
Yes, the library requires that a type T is ConstantCopyConstructible in order for a variable of such a type to have old value in postconditions. However, this constraint only applies for a type T tagged copyable by programmers by copyable<T>. Therefore, if T is not ConstantCopyConstructible, or simply if its old value is not needed in postconditions, programmers do not tag T copyable and the library does not add any constraint on T (plus there is no extra copy overhead for old). ConstantCopyConstructible is same as the CopyConstructible concept but the copy constructor must operate on a *const* source object "T::T(T const& source)". Regards, Lorenzo

Lorenzo Caminiti wrote:
Vicente:
Have you considered to add block invariants? Maybe you can complete the table Contract Programming Feature Comparison.
I think block invariants could be added if there was interest. Indeed, I have already implemented a class for Eiffel-like loop-contract with both invariants and variants (but I never use it in real code).
In the Contract Programming proposal for the C++ standard, block invariants are interesting also because they allow for additional compiler optimization but this benefit does not apply to a library.
I understand that this will not help the compiler to optimize, but why use a different technique to test the invariants of block? Why don't follow the C++ proposal in this case? Lorenzo Caminiti wrote:
If I have understood your library require the type is CopyConstructible to manage with postconditions. Have you considered to relax this constraint?
Yes, the library requires that a type T is ConstantCopyConstructible in order for a variable of such a type to have old value in postconditions. However, this constraint only applies for a type T tagged copyable by programmers by copyable<T>. Therefore, if T is not ConstantCopyConstructible, or simply if its old value is not needed in postconditions, programmers do not tag T copyable and the library does not add any constraint on T (plus there is no extra copy overhead for old).
ConstantCopyConstructible is same as the CopyConstructible concept but the copy constructor must operate on a *const* source object "T::T(T const& source)".
Imagine a class that is able to implement the ConstCopyConstructor but that don't wants to provide it to its users. This class can implement let me say a ContractCopyConstructor like C(C const& rhs, backup_t); When this constructor is defined your library could use it instead of the missing ConstCopyConstructor. We can go one step ahead an require from a class C that can be used on the post-condition of a function that there is another class with the same interface than C that can be copied from a const reference to C. Given the following trait template <typename T> struct backup { typedef T type; }; You can request instead of C(C const&) backup<C>::type(C const&); If a class C has a backup D, we will add the following specialization template <> struct backup<C> { typedef D type; }; This has some advantages: * separates the creation of real instances from the needed by your library. Thus avoiding the call to the CopyCOnstructor and destructor of the class which can have non desirable side effects. * allow to work with non-copyable classes * the user of your library could reduce the scope of operations used on this backup class making it more efficient, for example reducing the backed up fields or the implemented functions * the user can promote private or protected members to public. Of course this has also some liabilities: * the user needs to implement an additional class (optionally) At the end the default behavior of my design corresponds to your current behavior, letting the user the possibility to use more classes on the post-condition part. Can this design be adapted to your library? Just a last question, does your library avoid the evaluation of other contracts during execution of the post-condition? Best, Vicente -- View this message in context: http://old.nabble.com/-contract--Contract-Programming-Library-tp27024075p270... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi Vicente: On Thu, Jan 7, 2010 at 8:30 AM, Vicente Botet Escriba <vicente.botet@wanadoo.fr> wrote:
I understand that this will not help the compiler to optimize, but why use a different technique to test the invariants of block? Why don't follow the C++ proposal in this case?
Yes, I have added to look into block invariants to the library TODOs. As I said, it should be possible to implement block invariants, essentially just by handling BOOST_CONTRACT_ASSERT() within the block it self: void foo() { int i = 0; for(;;) BOOST_CONTRACT_BLOCK({ BOOST_CONTRACT_ASSERT(i < 10, "i less than 10"); ... }) } IMPLEMENTATION: The BOOST_CONTRACT_BLOCK() macro wraps the block with a try-catch statement to that will handle a boost::contract::failure exception invoking boost::contract::block_invariant_failed() (which will in turn terminate by default but can be redefined by the user). This would be very similar to the CP C++ Standard Proposal [Crowl2006].
Imagine a class that is able to implement the ConstCopyConstructor but that don't wants to provide it to its users. This class can implement let me say a ContractCopyConstructor like
C(C const& rhs, backup_t);
When this constructor is defined your library could use it instead of the missing ConstCopyConstructor.
We can go one step ahead an require from a class C that can be used on the post-condition of a function that there is another class with the same interface than C that can be copied from a const reference to C.
Given the following trait
template <typename T> struct backup { typedef T type; };
You can request instead of C(C const&)
backup<C>::type(C const&);
If a class C has a backup D, we will add the following specialization
template <> struct backup<C> { typedef D type; };
This has some advantages: * separates the creation of real instances from the needed by your library. Thus avoiding the call to the CopyCOnstructor and destructor of the class which can have non desirable side effects. * allow to work with non-copyable classes * the user of your library could reduce the scope of operations used on this backup class making it more efficient, for example reducing the backed up fields or the implemented functions * the user can promote private or protected members to public.
Of course this has also some liabilities: * the user needs to implement an additional class (optionally)
At the end the default behavior of my design corresponds to your current behavior, letting the user the possibility to use more classes on the post-condition part. Can this design be adapted to your library?
I see. Yes, this should be possible and I made a note in the library TODOs to experiment with this idea.
Just a last question, does your library avoid the evaluation of other contracts during execution of the post-condition?
No, but this is a policy question and the implementation could be changed if needed. The library should have enough internal infrastructure so that assertion checking can be disabled when needed (usually in order to avoid infinite recursion). The current policy that I have implemented follows the CP C++ Standard Proposal rev 1 [Ottosen2004]: 1) All assertions are disabled globally when any other assertion is being checked already. 2) In nested function calls of the same object, only invariant checking is disabled. Both Eiffel and the latest rev of the CP C++ Standard Proposal [Crowl2006] takes a different approach -- see Feature table of library documentation. In my CP projects, [Ottosen2004] policy has been more effective than [Crowl2006] in preventing infinite recursion. Plus [Ottosen2004] is closer to (but in my experience better than) Eiffel's policy. (Actually, [Crowl2006] policy would be easier to implement for the library.) I would like to discuss this point more and especially understand the reason / use case for changing this policy from [Ottosen2004] to [Crowl2006]. Regards, Lorenzo

Hello all, I simplified the library syntax as shown by the example below. I think with these changes the library matches very closely the Contract Programming C++ standard proposal (see n1962, Crowl and Ottosen, 2006). A notable difference is still the (unavoidable) many extra parenthesis required by the Boost.Preprocessor signature sequence. Comments? #include <contract.hpp> #include <vector> template<typename T> class myvector: public pushable<T> { CONTRACT_INVARIANT( ({ CONTRACT_ASSERT( (size() == 0) == empty() ); }) ) public: void push_back(const T& element) CONTRACT_FUNCTION( (class) (copyable)(myvector) (inherit)(pushable<T>) // Subcontracting. (public) (void) (push_back)( (const T&)(element) ) (precondition) ({ CONTRACT_ASSERT( size() < max_size() ); }) (postcondition) ({ CONTRACT_ASSERT( size() == (CONTRACT_OLDOF(this)->size() + 1) ); // Old value. }) (body) ({ vector_.push_back(element); }) ) private: std::vector<T> vector_; }; Major changes: 1) Removed use of self, variable.now, and variable.old in writing contracts. Object (this) and variables are now accessed as usual in member functions. `CONTRACT_OLDOF(variable)` is used to access old values in postconditions (users could `#define oldof(name) CONTRACT_OLDOF(name)` for convenience). 2) Added (precondition), (postcondition), and (body) to specify contracts within the function signature sequence. If no preconditions then `(precondition) ({...})` is simply omitted from the sequence (same for postconditions, body is mandatory instead). For non-void functions users can name the result argument with `(postcondition) (myresult) ({...})`. 3) Added block invariants and Eiffel-like loop variants (not shown above). 4) Added static class invariants which are always checked (also at constructors entry, destructor exit, and by static member functions -- not shown above). Regards, Lorenzo On Tue, Jan 5, 2010 at 1:28 PM, vicente.botet <vicente.botet@wanadoo.fr> wrote:
----- Original Message ----- From: "Lorenzo Caminiti" <lorcaminiti@gmail.com> To: <boost@lists.boost.org> Sent: Tuesday, January 05, 2010 6:54 AM Subject: [boost] [contract] Contract Programming Library
Hi all,
I am thinking to submit a library for Contract Programming (a.k.a. Design By Contract (TM) ) for C++.
I have drafted some of the library documentation in Boost-like format: http://dbcpp.sourceforge.net/boost/libs/contract/doc/html/
Comments?
Hi,
I find your library very interesting and except some unavoidable preprocessor ugly (), the syntax follows quite closely the C++ proposal.
Have you considered to add block invariants? Maybe you can complete the table Contract Programming Feature Comparison.
If I have understood your library require the type is CopyConstructible to manage with postconditions. Have you considered to relax this constraint?
I have taken the freedonm to add it to the Boost Libraries Under Construction https://svn.boost.org/trac/boost/wiki/LibrariesUnderConstruction . Let me know if all the informations are right.
Good work, Vicente
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (6)
-
Jason Felice
-
Lorenzo Caminiti
-
OvermindDL1
-
Thomas Klimpel
-
Vicente Botet Escriba
-
vicente.botet