Boost logo

Boost :

Subject: Re: [boost] [contract] Boost spoiled function declarations
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2010-05-18 09:04:38


> 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


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