Re: [boost] [contract] Boost spoiled function declarations

See examples below: Is Boost.Contract parenthesized syntax really more complex than Boost.Parameter or Boost.Interface?
1) While I recognize the ugliness of the Boost.Contract parenthesized syntax, I think it is actually simpler than Boost.Parameter or Boost.Interface syntax because it is essentially "the usual C++ syntax with all the tokens wrapped within parenthesis".
2) It is possible to provide Boost.Contract with macros similar to ones of Boost.Parameter.
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. 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. struct g { CONTRACT_CLASS( (g) ) BOOST_PARAMETER_MEMBER_FUNCTION( (void), depth_first_search, tag, (required (graph, *) ) (optional (visitor, *, boost::dfs_visitor<>()) (root_vertex, *, *vertices(graph).first) (index_map, *, get(boost::vertex_index, graph)) (in_out(color_map), *, default_color_map(num_verticies(graph), index_map)) ) ) CONTRACT_FUNCTION( (public) (template)( (typename)(graph_type) (typename)(visitor_type) (typename)(root_vertex_type) (typename)(index_map_type) (typename)(color_map_type) ) (void) (depth_firt_search)( (graph_type&)(graph) (visitor_type&)(visitor) (root_vertex_type&)(root_vertex) (index_map_type&)(index_map) (copyable)(color_map_type&)(color_map) ) (postcondition) ({ CONTRACT_ASSERT( color_map == CONTRACT_OLDOF(color_map) + 10 ); }) (body) ({ color_map += 10; std::cout << "graph=" << graph << std::endl; std::cout << "visitor=" << visitor << std::endl; std::cout << "root_vertex=" << root_vertex << std::endl; std::cout << "index_map=" << index_map << std::endl; std::cout << "color_map=" << color_map << std::endl; }) ) }; 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: struct g { CONTRACT_CLASS( (g) ) CONTRACT_NAMED_PARAM_FUNCTION( // a new macro (public) (void) (depth_firt_search)( (CONTRACT_NAMED_PARAM_REQUIRED_ARG(&graph) CONTRACT_NAMED_PARAM_OPTIONAL_ARG(&visitor)(boost::dfs_visitor<>()) CONTRACT_NAMED_PARAM_OPTIONAL_ARG(&root_vertex)(*vertices(graph).first) CONTRACT_NAMED_PARAM_OPTIONAL_ARG(&index_map)(get(boost::vertex_index, graph)) CONTRACT_NAMED_PARAM_OPTIONAL_ARG(copyable)(color_map_type&)(color_map) (default_color_map(num_verticies(graph), index_map)) ) (postcondition) ({ CONTRACT_ASSERT( color_map == CONTRACT_OLDOF(color_map) + 10 ); }) (body) ({ color_map += 10; std::cout << "graph=" << graph << std::endl; std::cout << "visitor=" << visitor << std::endl; std::cout << "root_vertex=" << root_vertex << std::endl; std::cout << "index_map=" << index_map << std::endl; std::cout << "color_map=" << color_map << std::endl; }) ) }; Obviously, my example is syntactically wrong and may be impossible, but I think you get the general idea. I am not sure if it is Boost's requirement that different libraries should interoperate smoothly with one another, but it would surely be elegant. I am not sure if this is achievable, as the macro tricks employed in the above libraries are beyond my comprehension. Also, it is not clear whether it should be a task for Boost.Contract maintainer or Boost.Parameter maintainer - the issue seems symmetrical. Regards, &rzej

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

On 18 May 2010 14:04, Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
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.
Not at all, that's up to the reviewers to decide. We don't have any requirement to respect a precedent set by another review. There could be reasons why it's good for one library, but not another. It might also be the case that experience with Boost.Parameter suggests that it's a bad idea or just that the Boost.Parameter reviewers did a bad job. Daniel

On Tue, May 18, 2010 at 1:44 PM, Daniel James <dnljms@gmail.com> wrote:
On 18 May 2010 14:04, Andrzej Krzemienski <akrzemi1@gmail.com> wrote:
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.
Not at all, that's up to the reviewers to decide. We don't have any requirement to respect a precedent set by another review. There could be reasons why it's good for one library, but not another. It might also be the case that experience with Boost.Parameter suggests that it's a bad idea or just that the Boost.Parameter reviewers did a bad job.
Yes, of course. I agree 100% with all your points: 1) Reviewers should/will decide. 2) No requirement to be bounded by Boost.Parameter review results at all but just to learn from them. 3) Boost.Parameter experience in allowing macros to spoil function declarations should be taken into account critically. Plus (4) API usability and (5) trade off between benefits and syntax complexity should be considered as well -- for example, (4) Boost.Parameter syntax could be easier to program than Boost.Contract and/or (5) named parameters might be more beneficial than contracts. I honestly think the only point we were trying to make is that Boost.Contract parenthesized syntax should not be excluded *a priori* given that Boost.Parameter also spoils function declarations adding a comparable amount of syntactic complexity. I am sorry if I gave a different impression. -- Lorenzo

On 18 May 2010 19:41, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
I honestly think the only point we were trying to make is that Boost.Contract parenthesized syntax should not be excluded *a priori* given that Boost.Parameter also spoils function declarations adding a comparable amount of syntactic complexity. I am sorry if I gave a different impression.
Okay, I misunderstood. I'm sorry that I jumped into the discussion without understanding the context. Daniel
participants (3)
-
Andrzej Krzemienski
-
Daniel James
-
Lorenzo Caminiti