Boost logo

Boost :

Subject: Re: [boost] [contract] Boost spoiled function declarations
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2010-05-18 11:20:00


Hi Andrzej!

On Tue, May 18, 2010 at 9:04 AM, Andrzej Krzemienski <akrzemi1_at_[hidden]> wrote:
>> See examples below: Is Boost.Contract parenthesized syntax really more
>> complex than Boost.Parameter or Boost.Interface?
> Hi,
> I think you are succesfully making the point that Boost.Contract
> syntax is no worse than that of Boost.Parameter; and since the latter
> made it into Boost, the syntax of Boost.Contract should be considered
> acceptable too.

Yes, this point was suggested to me by Thomas Klimpel in one of my
early Boost.Contract postings to Boost:

On Sun, Oct 18, 2009 at 6:01 PM, Thomas Klimpel
<Thomas.Klimpel_at_[hidden]> wrote:
> Doesn't Boost.Parameter also uses a foreign looking syntax? But I admit that "DBC_MEM_FUN" is a bit cryptic. How about BOOST_DBC_MEMBER_FUNCTION?

To be fare however, at that time Gottlob Frege also indicated that the
DSEL defined by Boost.Contract parenthesized syntax might have the
rather large domain of all your header files:

On Mon, Oct 19, 2009 at 3:30 AM, Gottlob Frege <gottlobfrege_at_[hidden]> wrote:
> Yes, Boost.Parameter is a bit odd as well.  And it makes me hesitate
> to use it - not avoid it, but hesitate - ie depends on where/how it is
> used.  Yet, in general, I like DSEL (domain-specific embedded
> languages), and have written a few.
> But here's the thing:
>   they are **domain-specific**
> This, for me at least, makes a big difference.  I don't mind seeing
> some strangeness within a certain domain or to solve a particular
> problem.  But when the augmented language is NOT domain-specific, and
> instead is used all over your code, then I start thinking that maybe
> we should just be using a different language.
> ...

In other words, while only a few functions might need to use
Boost.Parameter when named parameters are needed, quite a few
functions (all of them?) might need contracts and require the spoiled
parenthesized syntax. Therefore, the question would be: Can
Boost.Contract parenthesized syntax be considered acceptable even if
it has the possibility to extend to all your header files?

IMO, Boost.Parameter suffers the exact same issue because I might need
named parameters for all my functions as well as I might contracts for
all my functions. At the end, programmers will have to make the
choice: For how many functions is having contracts worth the
complexity of the parenthesized syntax? Unless the answer is known to
be 0 (and IMO even if the answer is "all"), I think Boost.Contract
syntax should be considered acceptable by Boosters.

IMO, another important aspect of this discussion is the actual
usability of the parenthesized syntax. Boost.Contract syntax might not
*look* worst than Boost.Parameter but is it "easy" to use as
Boost.Parameter is? However, until Boosters start experimenting with
using Boost.Contract (perhaps during the review process?), we can only
speculate about this.

> What is interesting is whether it is possible to define a function
> that validates contracts and allows named parameters at the same time.
> You already said it was possible. I paste an example from your post
> below.
> ...
> This example is for sure more complex than any Boost.Parameter or
> Boost.Contract. I believe it should be possible to add another set of
> macros that would allow defining functions with named parameters and
> contract verification in a more simpler manner. E.g. something like:

Yes, I successfully harmonized Boost.Contract with Boost.Parameter,
Boost.ConcetCheck, and enable_if<>.

1) For Boost.ConceptCheck I am using (requires) -- following the
proposed C++0x syntax also implemented by ConceptC++.
2) For Boost.Parameter I am using (in)/(inout)/(out) -- following
Boost.Parameter in_out()/out() and Ada in/'in out'/out syntax. (Also
Boost.Parameter type requirements and keyword namespace are supported
but I am not showing that here.)
3) enable_if<> can be used as always.

This examples shows how to program contracts, concepts, and named
parameters all together:

BOOST_PARAMETER_NAME(first)
BOOST_PARAMETER_NAME(last)
BOOST_PARAMETER_NAME(element)

class myvector: pubshable<T> {

    CONTRACT_CLASS( (myvector) (pushable<T>)
    (invariant)(
        (empty() == (size() == 0))
        ...
    ) )

public:

    // Contract for template, plus static member function, plus
concepts, plus named parameters.
    CONTRACT_FUNCTION(
    (public) (template)( (class)(Iter) ) // Function template.
        (requires)( // Concepts (interfaces with Boost.ConceptCheck).
            (boost::InputIterator<Iter>)
            (boost::EqualityComparable<T>)
        )
    (static) (bool) (all_equals)( // Static member.
            // For this example, using default named parameter keyword
namespace `tag`.
            (in) (Iter)(first) // Named input parameters (with exact
type requirements for this example).
            (in) (Iter)(last)
            (in) (const T&)(element)
        )
        (precondition)(
            (first < last)
        )
    ({
        for (Iter i = first; i < last; ++i) {
            if (*i != element) return false;
        }
        return true;
    }) )

    ...
};

(This code now compiles and runs on Boost.Contract latest development branch!)

Andrzej, this work was actually prompted by a comment you made to me a
while back saying that it would be good to have one single syntax for
all Boost libraries that spoil function declarations. Boost.Contract
parenthesized syntax above now does that -- thanks a lot for the idea!

-- 
Lorenzo

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