
on Mon Oct 24 2011, lcaminiti <lorcaminiti-AT-gmail.com> wrote:
Dave Abrahams wrote:
on Sat Oct 22 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> wrote:
On Fri, Sep 2, 2011 at 3:14 PM, Dave Abrahams <dave@> wrote:
on Fri Sep 02 2011, Lorenzo Caminiti <lorcaminiti-AT-gmail.com> wrote:
(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.
Hello all,
Here's how I am thinking to support named parameters within Boost.Contract's syntax.
Cool! Don't forget deduced parameters, though ;-)
Deduced params will be prefixed by the pp-keyword deduce. For example:
CONTRACT_FUNCTION( void (def) ( // skip optional keyword tag namespace in (char const*) name, // input required name with exact type in auto func, // input required function of any type // deduced optional params with exact and predicate type requirement deduce in (char const*) docstring, default "", deduce in requires(is_keyword_expression<_>) keywords, default no_keywords, deduce in requires(not_< or_<is_convertible<_, char const*>, is_keyword_expression<_> > >) policies, default default_call_policies ) precondition( ... ) postcondition( ... ) ) ;
Nicely done.
namespace tag, // optional namespace (tag assumed by default)
I'd really like to eliminate that if possible; it's quite off-putting. I guess if you can make it optional, that handles the problem.
Yes, the keyword tag namespace is always optional and tag is used by default (e.g., the python::def above did not specify the namespace).
in requires( // requires for type requirements
Why are we using "in" before "requires?" Requirements are not "in parameters."
This might be tricky... I need to prefix all named parameters with special "keywords" so the pp can distinguish them from positional parameters. In this case, I could just use requires and say that a parameter is named if prefixed by in, out, in out, or requires.
Yeah, that's what I was thinking.
However, I need to keep in, out, or in out for exact type requirements (not predicate) because they don't use requires. For example, this is a named parameter:
void (f) ( in (typename graph_traits<graph_type>::vertex_descriptor) root_vertex, default *vertices(graph).first, )
But this is a positional parameter (no in prefix):
void (f) ( (typename graph_traits<graph_type>::vertex_descriptor) root_vertex, default *vertices(graph).first, )
Can you please explain better why it might be a problem if I always use the in, out, in out specifiers even with predicate type requirements?
I'm sorry, maybe I misunderstood. I thought the requires( ... ) clause was not part of a parameter declaration. Ultimately it would probably be syntactically superior if requirements were separated, but if that's not the case I can certainly live with it.
I'd think ultimately, any parameter must have in, out, or in out semantic even if its type is specified using a metafunction predicate... isn't that ture? For example, depth_first_search documents /all/ its parameters as in, out, or in out: http://www.boost.org/doc/libs/1_47_0/libs/graph/doc/depth_first_search.html
Yeah... I think we said at one point that "in" was the default, but that feature may have fallen by the wayside.
I guess, to sum up, to evaluate the syntax I'd need to see the most beautiful possible realization of this algorithm as opposed to the most horrendous ;-).
I understand. Is this version more usable to judge the syntax?
No, it's still too dense because of the comments (and the redundant optional "namespace tag"). Try again, please :-)
#include <contract.hpp>
using namespace boost; using namespace boost::mpl::placeholders; using namespace boost::python;
namespace graphs {
BOOST_PARAMETER_NAME(graph) BOOST_PARAMETER_NAME(visitor) BOOST_PARAMETER_NAME(root_vertex) BOOST_PARAMETER_NAME(index_map) BOOST_PARAMETER_NAME(color_map)
// For simplicity, leaving out the use of BOOST_IDENTITY_TYPE for now. CONTRACT_FUNCTION( void (depth_first_search) ( // param keyword tag namespace (always optional, default to `tag`) namespace tag, // input required param with predicate type requirement (requires) in requires(is_incidence_and_vertex_list_graph<_>) graph, // input optional (default) param of any type (auto) in auto visitor, default dfs_visitor<>(), // input optional param with exact type requirement (parenthesized type) in (typename graph_traits<graph_type>::vertex_descriptor) root_vertex, default *vertices(graph).first, // input optional param with predicate type requirement (requires) in requires(is_integral_property_map_of_key<_, typename graph_traits< graph_type>::vertex_descriptor>) index_map, default get(vertex_index, graph), // input-output optional param with predicate type requirement in out requires(is_property_map_of_key<_, typename graph_traits< graph_type>::vertex_descriptor>) color_map, default default_color_map(num_vertices(graph), index_map) ) precondition( ... ) postcondition( ... ) ) ;
} // namespace graphs
I really appreciate your help on this, I only marginally understand Boost.Parameter. --Lorenzo
-- Dave Abrahams BoostPro Computing http://www.boostpro.com