Boost logo

Boost :

Subject: [boost] [contract] syntax redesign
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-05-31 14:49:54


Hello all,

After a long time of inactivity for Boost.Contract, I am considering
how to re-design its macro syntax to make it simpler.

I can eliminate a large number of extra parenthesis based on a few pp
tricks I've learned in processing Boost.Local's `const bind(type)&
var`. Plus, I can provide (optional) support for variadics macros so
to use comma-separated pp tuplets instead of parenthesized pp
sequences on preprocessors with variadics.

For example, I _think_ (but I've not implemented this yet) that I can
simplify the syntax like this:

#include <contract.hpp>
#include <vector>
#include "myvector/pushable.hpp"

// Wrapper class that adds contracts to std::vector.
CONTRACT_CLASS(
template( typename T )
class (myvector) extends( public pushable<T> ) // Subcontracting.
) {
    CONTRACT_CLASS_INVARIANT(
        empty() == (size() == 0)
        // More invariants here (comma separated)...
    )

    CONTRACT_FUNCTION(
    public void (push_back)( (const T&) element )
        precondition(
            size() < max_size()
            // More preconditions here (comma separated)...
        )
        postcondition(
            auto old_size = CONTRACT_OLDOF(size()), // Old value.
            size() == old_size + 1
            // More postconditions here (comma separated)...
        )
    ) {
        vector_.push_back(element); // Implementation.
    }

    // Rest of the class here (with more contracts if needed)...
public:
    typedef typename std::vector<T>::size_type size_type;
    size_type size(void) const { return vector_.size(); }
    size_type max_size(void) const { return vector_.max_size(); }
    bool empty(void) const { return vector_.empty(); }
    const T& back(void) const { return vector_.back(); }
private:
    std::vector<T> vector_;
};

For a side-by-side comparison with N1962 syntax:
    http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html/index.html#contract__.introduction.an_example
For a comparison of the entire std::vector (plus Boost.ConceptCheck concepts):
    http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html/contract__/examples.html
For a comparison for all Boost.Contract features (plus
Boost.ConceptCheck concepts and Boost.Parameter named parameters):
    http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html/contract__/tutorial.html#contract__.tutorial.a_fully_working_example
(Don't pay attention to the rest of the docs that are way out of date.)

A few notes:
* Extra parenthesis are still needed around class and function names.
* Extra parenthesis are still needed around types (like for the
parameter `(T) element`) but only if the type is not a C++ keyword (no
parenthesis needed aournd int, double, void, etc) or it contains a
symbol (parenthesis needed if & or * are used `(int&) x`, etc).
* In postconditions, the `auto old_size = CONTRACT_OLDOF(size())` only
copies the vector size (and not the entire vector :)) ). Similarly,
`auto result = return` can be used to access the return value for
non-void functions. (The `auto ...` is parsed by the pp and it's
implemented using Boost.Typeof so no C++0x is required.)
* Template declaration (but not instantiation) angular parenthesis <>
are replaced by round parenthesis ().
All of this _should_ be implementable in pure ISO C++.

What do you think? Based on the discontent that the previous
"parenthesized" syntax generated among Boosters, the key question is:
Would you consider this new syntax usable??

Thanks,
--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk