
Hi Andrzej! On Tue, May 18, 2010 at 9:04 AM, Andrzej Krzemienski <akrzemi1@gmail.com> 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@synopsys.com> 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@gmail.com> 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