Boost logo

Boost :

Subject: Re: [boost] [contract] syntax redesign
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-09-04 14:08:50


On Fri, Sep 2, 2011 at 3:14 PM, Dave Abrahams <dave_at_[hidden]> wrote:
>
> on Fri Sep 02 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> wrote:
>
>> For whomever is curious, I have implemented the new Boost.Contract
>> syntax. Here's large number of examples that now compile with the new
>> syntax:
>>     http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/examples.html
>
> Wow.  This is a powerful new language!  How does this relate to the work

Indeed, Boost.Contract defines a new DSEL which I named L++ ;) Here's
the complete grammar (draft):
    http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/grammar.html

IMO, what is very interesting about L++ when compared with other DSEL
(Boost.Phoenix, Boost.Lambda, etc) is that L++ is actually parsed all
the way up by the preprocessor. Therefore, L++ can use both
preprocessor and template meta-programming to implement it's features
(and not "just" template meta-programming). For example, this allows
to program the following basic Contract Programming rule:

    if a member function is not public then it does not check the
class invariants

This rule cannot be implemented using only template meta-programming
because (AFAIK) it is not possible to check if a function is public
using a C++ template meta-function like is_public<function-type>.
Instead a macro IS_PUBLIC(function-decl) can be written to parse the
L++ function declaration and expand to 1 if and only if the function
is public:

    #define IS_PUBLIC(function_decl) ...

    IS_PUBLIC( public void f ( int x ) ) // expand to 1
    IS_PUBLIC( private void g ( int y ) ) // expand to 0

> Matt Calabrese started on implementing concepts in C++11 (see the
> boostcon video)?

Matt and I have exchanged a couple of emails previously on this
thread. It looks like we are using similar pp techniques. However, I
will have to study Matt's work in more detail before I can really
comment...

> It looks like this can't possibly be quite right (can it?)
>
> http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/examples.html#contract__.examples.__n2081___find__generic_find_algorithm
>
> Don't you need a comma after "boost::InputIterator<Iter>"?

Yes, I fixed it (I compiled this example with
CONTRACT_CONFIG_NO_CONCEPTS which disables concepts so the compiler
did not error).

>> Highlights are:
>> * Side-by-side comparison with N1962 (contracts) and N2081 (concepts) syntax:
>>     http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/examples.html#contract__.examples.n1962_vector* I have also added C++0x-like virtual specifiers (final, override,
>> and new) to Boost.Contract:
>>     http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/examples.html#contract__.examples.mitchell02_counter* Side-by-side comparison with Eiffel syntax:
>>     http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/examples.html#contract__.examples.meyer97_stack4
>>
>> Comments are always welcome :)
>
> * Very impressive!  I might even try programming in this language.
> * How's debuggability (sorry for asking)?

After I have implemented the library I have to study:
1) Compile-time overhead (both pp and templates). This could be very
significant because the macros use tons of pp code and expand tons of
C++ template code.
2) Run-time overhead. This could also be very significant but mainly
because of Contract Programming itself. If all contracts are disabled
at compile-time that the run-time overhead should instead be 0.
3) Debuggability (integration with gdb, etc). This could be OK.
4) Integration with other tools like Doxygen, IntelliSense, etc. These
other tools might simply not work because they might not be able to
expand the macros (too complex pp code)... Boost.Wave should work
instead...

> * What's a "loop variant?"  I've heard of "loop invariants."

A loop variant is a non-negative integer expression that monotonically
decreases at each iteration of the loop (so it ensures that the loop
will terminate because it starts from 100, then 98, then 90,
eventually 0 and if less than 0 before the loop terminates the
contract is broken because the variant must be >= 0 and the program --
not just the loop :) -- terminates ).
http://en.wikipedia.org/wiki/Loop_variant.

Eiffel has loop variants, N1962 does not. I implemented them in
Boost.Contract but I can't argue they have been very useful for me...
http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/examples.html#contract__.examples.meyer97_gcd

>> (I still have to implement named parameter support (using
>> Boost.Parameter behind the scene) but that shouldn't be too hard. The
>> macros already parse the named parameter syntax using in/out/inout
>> "keywords".)
>
> I can't wait.

The grammar for positional, named, and deduced params is here:
http://svn.boost.org/svn/boost/sandbox/contract/libs/contract/doc/html2/contract__/grammar.html#contract__.grammar.function_parameters

Thanks for your comments!
--Lorenzo


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