Boost logo

Boost :

From: Rob Stewart (stewart_at_[hidden])
Date: 2005-07-09 15:21:56


From: Tobias Schwinger <tschwinger_at_[hidden]>
> Rob Stewart wrote:
> > From: Tobias Schwinger <tschwinger_at_[hidden]>
> >
> > > * test whether a type is a specific callable builtin type,
> >
> > ...specific, callable, built-in type;
> >
> > Note the trailing semicolon. Since some items in your list have
> > commas, you need to use semicolons to separate the list items.
>
> For all of them or just for the one with the commas?

All of them.

> > s/builtin/built-in/
> >
> > it specializes in the many properties of callable built-in
> > types.
>
> How about
>
> ... specializes in callable, built-in types.
>
> ??

Right, that should have been:

   ...specializes in the properties of callable, built-in types.

> >>About 300 overloads are needed for three different calling
> >>conventions and a maximum arity of 10. This calculation is
> >
> > You haven't mentioned "calling conventions" before this.
> > Shouldn't that be in the table?
>
> It /is/ there. Did you perhaps overlook it in the table?

Doh!

> >>* it can lead to a noticable slowdown,
> >
> > * can be slower,
>
> Slower than what?

I can ask the same thing for your version. We could
s/be/execute/ to clarify, but I'm not sure it is needed.

> >>client code to arbitrarily classify and decompose any of the
> >>type's multi-faceted properties:
> >
> > Boost.FunctionTypes addresses those disadvantages and allows
> > your code to arbitrarily classify and decompose any of a
> > function type's properties. The example becomes much simpler
> > as the function template's template argument list and formal
> > parameter type are reduced to "T":
>
> The beginning is good. It's still too lengthy for my taste. Btw: simpler than what?

Than the previous version of register_types.

> >>It can be desirable to transform callable built-in types. This
> >
> > In other situations, you may need to transform from one
> > callable built-in type to another.
>
> I try to avoid 2nd person singular except for "please note blocks."
>
> Another situation is to ...

I was trying to convey that the idea that the reader could well
encounter the situation. I was trying to make it less
theoretical.

> Isn't that "from one to another"-thing implied by "tranform?"

Yes, in part, but that phrase adds clarity for me.

   There are situations that require transforming one callable
   built-in type into another.

> > The example for that should really build upon the previous
> > example:
> >
> > template<typename F>
> > void facility::register_function(F f)
> > {
> > boost::function<typename function_type<F>::type> wrapped = f;
> > // call wrapped as appropriate
> > }
>
> It's intentional because it makes little sense in this context: You'ld usually
> want to do declare the boost::function at class scope (of a different class).

So use a footnote to explain the shortcut taken for brevity's
sake.

> More details on this issue can be found below.

OK.

> > As you can now see, I think you should develop register_function() as you go
> > along so the reader can see the reason for each aspect for which
> > Boost.FunctionTypes can offer help.
>
> As stated above it's not that easy and would require more infrastructure around
> the examples.
>
> Previous example:
>
> template<typename T>
> void facility::register_function(T a)
> {
> < // [...] <-- use Boost.FunctionTypes on T
> > BOOST_MPL_ASSERT_MSG(is_callable_scalar<T>::value
> > ,NO_CALLABLE_SCALAR_TYPE, (T));
> > this->callback = action<T>(a); // <-- uses Boost.FunctionTypes on T
> }
>
> Then:
>
> template<typename F> class action
> {
> boost::function<typename function_type<F>::type> wrapped;
>
> action(F f)
> : wrapped(f)
> // ...
> };
>
> Well, what I don't like about it (besides that there's more infrastructure around
> the actual thing) is that both are not necessarily the same case. I'm not feeling
> too strong about it, though (at least when there are headlines for every use case).

You can transform the free function into a member function when
you reach that point. If the function has the same name and
effective arguments after the transformation, it should make
sense and will still help to tell the story.

> >>When taking the address of an overloaded function or function
> >>template, the type of the function must be told to the
> >>compiler.
> >
> > This part seems abrubtly different from the preceding text and
> > examples. Does it fit with register_function() somehow or is it
> > unrelated?
>
> Actually, all three are different.
>
> > If the latter, might I suggest that you delineate
> > that separation?
>
> I'ld have to add a headline for all of them (I wanted to do so but failed finding
> good titles so I left it out, for now).

If there's a way to work that in with the same example, it would
help the reader. Otherwise, it is harder to follow.

> >>Boost.FunctionTypes can help automating it.
> >
> > Fortunately, Boost.FunctionTypes can help to automate those
> > cases:
>
> Not sure about the "fortunately" -- the rest of it is bought.

OK, omit "fortunately."

> > "The third trivial example above in a nondeduced context of a
> > function template" is practically useless. One has to work so
> > hard to grok that phrase that one is unlikely to do it, so the
> > example isn't likely to be of much value.
> >
> > What would be useful is to show exactly how to solve the
> > std::for_each example.
>
> The problem is that you won't need the library for the std::for_each example.

Then why is it an example of a problem in your introduction?

Pick one of the other examples and show exactly how to solve it.
What you did does not solve one of the examples you gave.

> > Don't leave more than necessary as an
> > exercise for the reader. This is the introduction and you want
> > to show how your library is actually used to solve real problems.
> >
> > feed_tuple_to_function references "Fusion" tuples. I presume
> > those are part of the project under development for Boost that
> > has yet to be accepted (so far as I recall). Why introduce what
> > is likely to be foreign to many readers in your introduction?
>
> It's a sub library of Boost.Spirit since Boost 1.31 (Fusion as a stand-alone
> library has yet to accepted, though).

So if the reader hasn't used Boost.Spirit, the reader will
probably not know about Fusion.

> You don't have to be too familiar with Fusion to understand what's happening here.

Nevertheless, it is something unfamiliar introduced without
providing help in understanding your library.

> >>Note that this technique is generally not well-suited to serve
> >>as an interface for generic facilities because it has many
> >>limitations, such as requiring a known result type and the
> >>exact parameter types (rather than types for possible
> >>arguments) and because feed_tuple_to_function cannot be
> >>overloaded.
> >
> > After looking at the example and reading that text, I'm left to
> > wonder what value the example offers.
>
> Not everything has to be entirely generic to make sense and not every technique
> out there is for creating interfaces of generic libraries...

I don't think that note is helpful in an introduction then. It
leads the reader to question why you presented the example. You
can reserve such caveats for a more advanced section of the
documentation.

> > Is it something a person needs to do with any regularity (something I'd expect from a
> > library introduction)?
>
> There's not much regularity in the exact case shown by the example. However
> overload selection (the principle behind the example) is an important use case and
> should be shown here.

OK, I see what I didn't like about the text now. Starting with
"Assuming these declarations," you should rework the text (not
the note) like this:

   Boost.FunctionTypes also helps when selecting from among
   overloaded functions. Assuming these declarations

      ...

   it is possible to select the first overload of
   overloaded_function and the function_template<int,long>
   specialization when using a tuple with int and long in it:

      ...

(This may be where you have to use Fusion tuples, but if you can
use MPL instead, I think that would be wise.)

-- 
Rob Stewart                           stewart_at_[hidden]
Software Engineer                     http://www.sig.com
Susquehanna International Group, LLP  using std::disclaimer;

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