Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-11-23 14:26:00


Doug Gregor <dgregor_at_[hidden]> writes:

> My review of the named parameters library follows:
>
>> - What is your evaluation of the design?
>
> The design is good. The library improves the syntax of named
> parameters greatly relative to existing solutions, makes it trivial to
> define new keywords, provides a simple DSL for specifying default
> parameters, and has some useful shortcuts.
>
> I have a few issues with the interface:
>
> 1) We need a params.has(k) member, that returns mpl::true_ when the
> parameter is there and mpl::false_ when the parameter is not
> there. That lets us dispatch either statically or dynamically based
> on the existence of an argument for keyword k.

Seems like that interface makes static dispatch unneccessarily hard.
How about a metafunction:

    has_param<Params, k>

such that

    has_param<Params, k>

is derived from either mpl::true_ or mpl::false_ and

    has_param<Params, k>::type

is one of mpl::true_ or mpl::false_.

??

> 2) The macro BOOST_NAMED_PARAMS_FUN is okay when all parameters may be
> named parameters. In my use cases, there are always several
> positional-only parameters for which I do *not* want the option to
> rename them, and may want to be more picky about how they are
> passed to the function. For instance, I want to be able to take a
> "Graph& g" as the first parameter. One way to address this would be
> another variant of this macro, which I'll lamely call
> BOOST_NAMED_PARAMS_FUN_EXT, that might work like this:
>
> BOOST_NAMED_PARAMS_FUN_EXT(void, page_rank, 0, 3, detail::page_rank_keywords,
> (2, (typename Graph, typename RankMap)),
> (2, ((Graph&, g), (RankMap rank))))
>
> The first new argument is a preprocessor array giving the extra
> template parameters that should be introduced into the function. The
> second new argument is also a preprocessor array, this one containing
> the parameter types and names (each as tuples). I believe there is
> enough information here to generate, e.g.,
>
> template<typename Graph, typename RankMap>
> void page_rank(Graph& g, RankMap rank)
> { return page_rank_with_named_params(g, rank,
> detail::page_rank_keywords()()); }
>
> template<typename Graph, typename RankMap, typename T0>
> void page_rank(Graph& g, RankMap rank, const T0& a0)
> { return page_rank_with_named_params(g, rank,
> detail::page_rank_keywords()(a0)); }
>
> etc...

Probably something like that could work. But my intuition tells me
this is a good candidate for vertical repetition:

  #ifndef BOOST_PP_IS_ITERATING

  ...

  # define BOOST_NAMED_PARAMS_SETUP(whatever.hpp, 2, 5)
  # include BOOST_NAMED_PARAMS_GENERATE
  #else

  template <class Graph, class RankMap BOOST_NAMED_PARAMS_TYPES>
  void page_rank(Graph& g, RankMap rank BOOST_NAMED_PARAMS_ARGS)
  {
    return page_rank_with_named_params(
        g, rank, BOOST_NAMED_PARAMS_KEYWORDS);
  }

  #endif

Otherwise it's just too ugly and unreadable, not to mention what
happens when types contain commas.

> 3) Partly due to the missing "params.has(p)", we're lacking the
> ability to determine the type of an expression like
> "params[index_map | get(vertex_index, g)]" without passing it to
> another function. I'd gladly give up some clarity in the handling
> of default parameters if I could get at this information. I'd even
> go for an auto-like macro:
>
> BOOST_NAMED_PARAMS_AUTO(index, index_map, get(vertex_index, g));

Yikes; that one is hard without some kind of typeof support.

How about:

         BOOST_NAMED_PARAMS_AUTO(index, index_map, some-type-expression);

??

You already have some way to look up the type of

  get(vertex_index, g)

right?

> If we had both (2) and (3), it would be feasible to implement
> algorithms such as those in the graph library without manually
> introducing several layers of forwarding functions used only to
> determine types.
>
> 4) Using the name "restrict" in a public interface feels like a really
> bad idea given its status in C99...

Yeah, we should change that.

> The documentation was a little bit lacking. There were a few specific
> things I would like to see:
>
> 1) A "guide for library writers" that helps one organize a library
> properly for named parameters. For instance, where should we put
> keywords? I know we should use an anonymous namespace, but should
> that be in namespace boost? In a "keywords" subnamespace?

Okay.

> 2) Keywords are stated to be of type "boost::keyword<keyword
> type>". Can we derive from the appropriate boost::keyword<...>
> instead? This is important to the BGL for backward compatibility
> reasons.

I honestly don't know. If we can, we should enable it.

> 3) Describing that operator, exists would be helpful.

Definitely.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

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