[review] Fast track formal review of Forward library begins today

Hi all, The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today : Boost.Functional/Forward provides decorator function objects to have an n-ary, generic function object accept both RValues and mutable LValues. An exponential number of overloads is needed with C98, so redundant solutions are highly undesirable. Functional/Forward is a reusable implementation asking to live in a central place in Boost. Download it from here: http://www.boost-consulting.com/vault/index.php?action=downloadfile&filename=forward.zip&directory=X-Files& http://www.boost-consulting.com/vault/index.php?&direction=0&order=&directory=X-Files The documentation is included in the .zip file, in the usual place: forward/libs/functional/forward/doc/html/index.html What to include in Review Comments ================================== Your comments may be brief or lengthy, but basically the Review Manager needs your evaluation of the library. If you identify problems along the way, please note if they are minor, serious, or showstoppers. Here are some questions you might want to answer in your review: * What is your evaluation of the design? * What is your evaluation of the implementation? * What is your evaluation of the documentation? * What is your evaluation of the potential usefulness of the library? * Did you try to use the library? With what compiler? Did you have any problems? * How much effort did you put into your evaluation? A glance? A quick reading? In-depth study? * Are you knowledgeable about the problem domain? And finally, every review should answer this question: * Do you think the library should be accepted as a Boost library? Be sure to say this explicitly so that your other comments don't obscure your overall opinion. We're looking forward to your evaluation of this Boost candidate! John Torjo - Review Manager - -- http://John.Torjo.com -- C++ expert ... call me only if you want things done right

Some users asked for the docs to be posted online. So, here they are: http://www.torjo.com/tobias/ John Torjo - Review Manager -
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
Boost.Functional/Forward provides decorator function objects to have an n-ary, generic function object accept both RValues and mutable LValues.
An exponential number of overloads is needed with C98, so redundant solutions are highly undesirable. Functional/Forward is a reusable implementation asking to live in a central place in Boost.
Download it from here:
http://www.boost-consulting.com/vault/index.php?action=downloadfile&filename=forward.zip&directory=X-Files& http://www.boost-consulting.com/vault/index.php?&direction=0&order=&directory=X-Files
-- http://John.Torjo.com -- C++ expert ... call me only if you want things done right

on Mon Dec 03 2007, John Torjo <john.groups-AT-torjo.com> wrote:
* What is your evaluation of the design?
Looks good to me.
* What is your evaluation of the implementation?
Also looks good, although I don't understand the PP approach being used. It certainly looks different from the very fast one that Paul Mensonides put together for me once (attached at bottom), but I'm willing to believe it's better. Comments would be helpful. It should use compressed_pair to store the wrapped function object to take advantage of EBO.
* What is your evaluation of the documentation?
Nice, but terse. It would probably be helpful to many to add some more material explaining the forwarding problem.
* What is your evaluation of the potential usefulness of the library?
Huge
* Did you try to use the library? With what compiler? Did you have any problems?
No, n/a, and no
* How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
A quick reading
* Are you knowledgeable about the problem domain?
Yeah
And finally, every review should answer this question:
* Do you think the library should be accepted as a Boost library?
Absolutely. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Dave, thanks for your review and the positive vote. David Abrahams wrote:
on Mon Dec 03 2007, John Torjo <john.groups-AT-torjo.com> wrote:
* What is your evaluation of the design?
Looks good to me.
* What is your evaluation of the implementation?
Also looks good, although I don't understand the PP approach being used.
It's quite simple, in fact: Looking at the bits of a counter with loop unrolling applied (not to hit the limits of the PP lib for arities > 8).
It certainly looks different from the very fast one that Paul Mensonides put together for me once (attached at bottom),
Interesting! I never noticed that SEQ_PRODUCT macro actually takes an arbitrary number of factors - pretty cool...
but I'm willing to believe it's better.
Well, I'm not :-). That is, not without at least taking a closer look. Running a quick benchmark shows -to my very surprise- that the performance difference is rather insignificant (at least with GCC/Darwin). Even more surprisingly my code starts outperforming Paul's at max.arity>7. I believe Paul's code can theoretically run a lot faster with a preprocessor that is well-optimized for metaprogramming (not sure there is one around) and it has the "wizardry bonus". Mine OTOH emits at least a few newline characters - which I happen to like :-). Anyway, I will benchmark with some more compilers and eventually change things to use Paul's approach if a significant advantage becomes apparent.
Comments would be helpful.
OK.
It should use compressed_pair to store the wrapped function object to take advantage of EBO.
The class only has a single member, so how would it be applicable? We could just inherit the target function privately to exploit EBCO in cases when inheriting from 'forward<F>'...
* What is your evaluation of the documentation?
Nice, but terse. It would probably be helpful to many to add some more material explaining the forwarding problem.
Are you missing something in particular? BTW: "Virgin guinea pig readers" out there? - Don't hesitate, you're always welcome... Regards, Tobias

on Tue Dec 04 2007, Tobias Schwinger <tschwinger-AT-isonews2.com> wrote:
I believe Paul's code can theoretically run a lot faster with a preprocessor that is well-optimized for metaprogramming (not sure there is one around) and it has the "wizardry bonus". Mine OTOH emits at least a few newline characters - which I happen to like :-).
Anyway, I will benchmark with some more compilers and eventually change things to use Paul's approach if a significant advantage becomes apparent.
I think you might find yourself wanting to use both approaches, depending on the compiler :(
It should use compressed_pair to store the wrapped function object to take advantage of EBO.
The class only has a single member, so how would it be applicable?
Just make the other element of the pair an empty class.
We could just inherit the target function privately to exploit EBCO in cases when inheriting from 'forward<F>'...
That won't work when the target function is a function pointer. compressed_pair handles these issues automatically.
* What is your evaluation of the documentation?
Nice, but terse. It would probably be helpful to many to add some more material explaining the forwarding problem.
Are you missing something in particular?
Yeah, a little segment that goes, "suppose you're trying to do this: ... . So you implement it this way ... and then this problem ... happens. So you try doing this ... and that problem .... happens. What you should do instead is use the forwarding library like this: ...." -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

John Torjo wrote:
* What is your evaluation of the design?
simple and effective. I'd like to see more tweakable parameters for specific uses. I frequently deal with different number expansions in a case to case basis. For example, is it possible to have arity 3 for function X and arity-5 for function Y? A single number seems wasteful if I'm sure that a certain use needs only a few. Is that possible?
* What is your evaluation of the implementation?
again, simple and effective.
* What is your evaluation of the documentation?
concise and sufficient for its purpose. I'd like to see more information on result type deduction though. It says: "Boost.ResultOf can be used to determine the result types of specific call expressions.". Ok, but what does that really imply? It would be good to have some information on this and its implications. For instance, for polymorphic function objects, do we have to supply all the nested /result/ metafunction for all overloads? How can the forward_adapter template know what to return? Etc. A more useful example would be one that actually returns something (instead of just void). I'd like to see an example for a polymorphic function.
* What is your evaluation of the potential usefulness of the library?
It's been in use in fusion for quite some time now. Very useful. Without this, and before this, we had to resort to lots of code duplication with tons of macro expansions everywhere.
* Did you try to use the library? With what compiler?
It's been part of fusion which is already well tested.
Did you have any problems?
Nope.
* How much effort did you put into your evaluation?
As main author of fusion, I do a review of all code and components going into fusion.
A glance? A quick reading? In-depth study?
See above.
* Are you knowledgeable about the problem domain?
Yes.
And finally, every review should answer this question:
* Do you think the library should be accepted as a Boost library? Be sure to say this explicitly so that your other comments don't obscure your overall opinion.
Yes. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

on Tue Dec 04 2007, Joel de Guzman <djowel-AT-gmail.com> wrote:
John Torjo wrote:
* What is your evaluation of the design?
simple and effective. I'd like to see more tweakable parameters for specific uses. I frequently deal with different number expansions in a case to case basis. For example, is it possible to have arity 3 for function X and arity-5 for function Y? A single number seems wasteful if I'm sure that a certain use needs only a few. Is that possible?
It generates one template definition. You could generate a bunch of different templates for different uses but I don't see much advantage; it would probably slow down compilation overall. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

Joel, thanks for this review. Joel de Guzman wrote:
John Torjo wrote:
* What is your evaluation of the design?
simple and effective. I'd like to see more tweakable parameters for specific uses. I frequently deal with different number expansions in a case to case basis. For example, is it possible to have arity 3 for function X and arity-5 for function Y? A single number seems wasteful if I'm sure that a certain use needs only a few. Is that possible?
Yes, I think so. And it turns out to be a very good idea, as it potentially makes overload resolution *a lot* faster. Here comes the benchmark compiling do_the_bind.cpp, ported to use the forward adapter with gcc: Arity=8 preprocess real 0m1.384s user 0m1.270s sys 0m0.109s preprocess, compile, link real 0m12.405s user 0m11.769s sys 0m0.540s Arity=4 preprocess real 0m0.918s user 0m0.454s sys 0m0.081s preprocess, compile, link real 0m1.949s user 0m1.653s sys 0m0.268s Interestingly preprocessing is a minor concern and so we could even provide means to take our pick at compile time (as opposed to preprocessing time).
* What is your evaluation of the implementation?
again, simple and effective.
* What is your evaluation of the documentation?
concise and sufficient for its purpose. I'd like to see more information on result type deduction though. It says: "Boost.ResultOf can be used to determine the result types of specific call expressions.". Ok, but what does that really imply? It would be good to have some information on this and its implications. For instance, for polymorphic function objects, do we have to supply all the nested /result/ metafunction for all overloads?
I see. This question really shouldn't be left unanswered.
How can the forward_adapter template know what to return?
"By applying result_of" - anything beyond that should probably be said within the docs of ResultOf...
I'd like to see an example for a polymorphic function.
...which also might be the more appropriate place for such an example. Slightly slipping off topic, I wonder whether the docs of ResultOf been updated to refer to the current version of the specification (with changed semantics for reference types). We should really get this taken care of before 1.35 goes out. Regards, Tobias

Joel wrote:
I'd like to see more tweakable parameters for specific uses. I frequently deal with different number expansions in a case to case basis. For example, is it possible to have arity 3 for function X and arity-5 for function Y? A single number seems wasteful if I'm sure that a certain use needs only a few. Is that possible?
Yes, I think so. And it turns out to be a very good idea, as it potentially makes overload resolution *a lot* faster. Here comes the benchmark compiling do_the_bind.cpp, ported to use the forward adapter with gcc:
Arity=8 preprocess
real 0m1.384s user 0m1.270s sys 0m0.109s
preprocess, compile, link
real 0m12.405s user 0m11.769s sys 0m0.540s
Arity=4 preprocess
real 0m0.918s user 0m0.454s sys 0m0.081s
preprocess, compile, link
real 0m1.949s user 0m1.653s sys 0m0.268s
Wow that's interesting. Is the trend exponential? Can't really tell with just 2 sample points.
Interestingly preprocessing is a minor concern and so we could even provide means to take our pick at compile time (as opposed to preprocessing time).
Not so fast. Don't forget EDG. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Joel wrote:
I'd like to see more tweakable parameters for specific uses. I frequently deal with different number expansions in a case to case basis. For example, is it possible to have arity 3 for function X and arity-5 for function Y? A single number seems wasteful if I'm sure that a certain use needs only a few. Is that possible? Yes, I think so. And it turns out to be a very good idea, as it potentially makes overload resolution *a lot* faster. Here comes the benchmark compiling do_the_bind.cpp, ported to use the forward adapter with gcc:
Arity=8 preprocess
real 0m1.384s user 0m1.270s sys 0m0.109s
preprocess, compile, link
real 0m12.405s user 0m11.769s sys 0m0.540s
Arity=4 preprocess
real 0m0.918s user 0m0.454s sys 0m0.081s
preprocess, compile, link
real 0m1.949s user 0m1.653s sys 0m0.268s
Wow that's interesting. Is the trend exponential? Can't really tell with just 2 sample points.
Yeah, seems so: 4 -> 1.4 5 -> 1.5 6 -> 2 7 -> 3 8 -> 11.2 (compile & link time only) And these are just a few calls - we can easily have a higher constant in practice...
Interestingly preprocessing is a minor concern and so we could even provide means to take our pick at compile time (as opposed to preprocessing time).
Not so fast. Don't forget EDG.
No panic, I will also allow fractional preprocessing :-). The idea to (almost) mostly pay for what one knows to use at compile time (rather than what one assumes one might need at preprocessing time) makes compile time control a tempting feature to have, however. Regards, Tobias

Tobias Schwinger wrote:
Interestingly preprocessing is a minor concern and so we could even provide means to take our pick at compile time (as opposed to preprocessing time). Not so fast. Don't forget EDG.
No panic, I will also allow fractional preprocessing :-). The idea to (almost) mostly pay for what one knows to use at compile time (rather than what one assumes one might need at preprocessing time) makes compile time control a tempting feature to have, however.
Sounds good :-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

On Dec 3, 2007 10:57 AM, John Torjo <john.groups@torjo.com> wrote:
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
* What is your evaluation of the design?
Good. Simple enough to cover most needs. In my design I allow the user to specify if a specific operator() overload should be disabled or not (depending on the arity and the parameter types); It is useful if you are using more than one forwarder in some complex composition (i.e. as base classes) and you need to disable ambiguous overload. I do not think Boost.Functional/Forward should necessarily provide this functionality, but it might be considered. I think too that the library should optionally allow K more arguments which are all const or non const. For (uncommon) very high arity functions that need to be wrapped, you can usually live with this limitation.
* What is your evaluation of the implementation?
Looks simple, but it is hard to evaluate preprocessor meta code.
* What is your evaluation of the documentation?
Complete enough. I think it should be explicitly specified that the wrapped function object must be result_of compatible (if such a note is already present, I've missed it). A discussion of the impact of the library on compile time (especially with high values of N) would be useful. Also a comment on the (potentially lack of) runtime performance penalty imposed by the library would be nice.
From the documentation I cannot infer if operator() is overloaded for both const and non const 'this'. I think not (), but it should be specified explicitly. I have never needed this in practice, In fact, IMHO it should be specified that 'this' is always const.
* What is your evaluation of the potential usefulness of the library?
Extremely useful. This is wheel which has been reinvented many and many times. Boost should be the supply a prepackaged solution.
* Did you try to use the library? With what compiler?
No.
Did you have any problems?
N/A.
* How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
A quick reading of the documentation and of the implementation.
* Are you knowledgeable about the problem domain?
Yes, I'm one of those which had to reimplement the wheel :).
* Do you think the library should be accepted as a Boost library?
Definitely! gpd

On Dec 5, 2007 11:27 AM, Giovanni Piero Deretta <gpderetta@gmail.com> wrote:
[...] * What is your evaluation of the design? [...] In my design I allow the user to specify if a specific operator() overload should be disabled or not (depending on the arity and the
On Dec 3, 2007 10:57 AM, John Torjo <john.groups@torjo.com> wrote: parameter types); It is useful if you are using more than one forwarder in some complex composition (i.e. as base classes) and you need to disable ambiguous overload. I do not think Boost.Functional/Forward should necessarily provide this functionality, but it might be considered.
Almost forgot, I also allow to (optionally) specify an accessor to get to the forwarded function object give this and also specify a metafunction to get the result value for a specific overload. The operator() definition of my forwarder (with pseudo vararg syntax) looks something like this: template<typename Args...> typename my_result_of(Base(Args...>)::type operator()(Args... argn) const { return typename access::apply<Base(Args...)>::type()(*this)(argn...); } Where 'my_result_of' is a composition of metafunctions provided by the user that does both SFINAE and type deduction, and 'access' is a metafunction class provided by the user that returns a (stateless) function object which in turn returns the object to be forwarded. The default of course is to do respectively no SFINAE, forward to result_of and static_cast to Base. In particular 'access' is useful if you, for whatever reason, want to reverse the inheritance order and use the CRTP. Again, this is probably getting too complex for a simple utility. -- gpd

Giovanni, thanks for your review. Giovanni Piero Deretta wrote:
On Dec 3, 2007 10:57 AM, John Torjo <john.groups@torjo.com> wrote:
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
* What is your evaluation of the design?
Good. Simple enough to cover most needs.
In my design I allow the user to specify if a specific operator() overload should be disabled or not (depending on the arity and the parameter types); It is useful if you are using more than one forwarder in some complex composition (i.e. as base classes) and you need to disable ambiguous overload. I do not think Boost.Functional/Forward should necessarily provide this functionality, but it might be considered.
Yes, we have been there (with Fusion) and recently dropped this functionality when porting to Boost.ResultOf: We used to have an empty 'result' metafunction say "disable this overload", exploiting SFINAE where applicable. ResultOf, however, does not propagate emptiness by specification as a matter of downward compatibility (no SFINAE inside the operand of 'decltype'). I personally still have mixed emotions about the loss.
I think too that the library should optionally allow K more arguments which are all const or non const. For (uncommon) very high arity functions that need to be wrapped, you can usually live with this limitation.
* What is your evaluation of the implementation?
Looks simple, but it is hard to evaluate preprocessor meta code.
* What is your evaluation of the documentation?
Complete enough.
I think it should be explicitly specified that the wrapped function object must be result_of compatible (if such a note is already present, I've missed it).
OK, here is some overlap with Joel's complaints. It seems I should add some detail in regard to result_of usage.
A discussion of the impact of the library on compile time (especially with high values of N) would be useful.
Yes, I think the final version will have a it and give the user more control over the N (see my reply to Joel's review).
Also a comment on the (potentially lack of) runtime performance penalty imposed by the library would be nice.
That would be "the lack thereof with a decent compiler". That is there are no constructs that force the compiler to emit code - though it's still free to do so.
From the documentation I cannot infer if operator() is overloaded for both const and non const 'this'. I think not (), but it should be specified explicitly.
Count it as a bug.
I have never needed this in practice, In fact, IMHO it should be specified that 'this' is always const.
Considerable, but I believe I want to think some more about it :-). Regards, Tobias

On Dec 3, 2007 2:57 AM, John Torjo <john.groups@torjo.com> wrote:
* What is your evaluation of the design?
Clear enough. I would find the gref metafunction useful factored out in a separate include file (with a more descriptive name than gref like... forwardable<T>::type? lvalue_reference_to_which_is_bindable<T>::type :) ?)
* What is your evaluation of the implementation?
I agree with Dave on the EBO suggestion (and thanks for the compressed_pair lesson)
* What is your evaluation of the documentation?
Sufficient.
* What is your evaluation of the potential usefulness of the library?
Very useful. Although, I seem to run into cases where I want to have a forwarding function (not function object), or a forwarding operator. But maybe I'm wrong in preferring an actual function...
* Did you try to use the library? With what compiler? Did you have any problems?
GCC 4.0.1/darwin. I expanded the example from the docs a bit to where the forwarded function was polymorphic with varying return type. No problems.
* How much effort did you put into your evaluation? A glance? A quick reading? In-depth study?
Read the docs, studied the implementation until I mostly understood what it was doing, contemplated it a bit, and gave it a quick try.
* Are you knowledgeable about the problem domain?
I have a few bumps on my head, courtesy of the forwarding problem.
And finally, every review should answer this question:
* Do you think the library should be accepted as a Boost library? Be sure to say this explicitly so that your other comments don't obscure your overall opinion.
Yes - thanks for another great contribution. Stjepan

Stjepan, thanks for reviewing the Forward utility. Stjepan Rajko wrote:
On Dec 3, 2007 2:57 AM, John Torjo <john.groups@torjo.com> wrote:
* What is your evaluation of the design?
Clear enough. I would find the gref metafunction useful factored out in a separate include file (with a more descriptive name than gref like... forwardable<T>::type? lvalue_reference_to_which_is_bindable<T>::type :) ?)
It sorta exists already, as 'gref' is basically a more primitive version of 'call_traits<T>::param_type.
* What is your evaluation of the implementation?
I agree with Dave on the EBO suggestion (and thanks for the compressed_pair lesson)
From my personal feeling inheriting from 'forward<F>' might be too rare of a use case to optimize for. However, with two reviewers asking for it I'll probably end up drowning my possibly premature assumptions on what the user will or will not do in a sea of genericity :-)...
* What is your evaluation of the documentation?
Sufficient.
* What is your evaluation of the potential usefulness of the library?
Very useful. Although, I seem to run into cases where I want to have a forwarding function (not function object), or a forwarding operator. But maybe I'm wrong in preferring an actual function...
Something like 'make_forward_adapter'? Regards, Tobias

On Dec 7, 2007 2:51 AM, Tobias Schwinger <tschwinger@isonews2.com> wrote:
Stjepan Rajko wrote:
Clear enough. I would find the gref metafunction useful factored out in a separate include file (with a more descriptive name than gref like... forwardable<T>::type? lvalue_reference_to_which_is_bindable<T>::type :) ?)
It sorta exists already, as 'gref' is basically a more primitive version of 'call_traits<T>::param_type.
Bah, I was under the misconception that, e.g., call_traits<int>::param_type is int, but it's actually const int... param_type is what I need, thanks.
* What is your evaluation of the implementation?
I agree with Dave on the EBO suggestion (and thanks for the compressed_pair lesson)
From my personal feeling inheriting from 'forward<F>' might be too rare of a use case to optimize for. However, with two reviewers asking for it I'll probably end up drowning my possibly premature assumptions on what the user will or will not do in a sea of genericity :-)...
I tend to be inheritance-happy :-) Are there any arguments against implementing forward<F> using inheritance of (compressed_pair of) F?
* What is your evaluation of the potential usefulness of the library?
Very useful. Although, I seem to run into cases where I want to have a forwarding function (not function object), or a forwarding operator. But maybe I'm wrong in preferring an actual function...
Something like 'make_forward_adapter'?
You mean like 'make_fused', etc...? No, I meant instead of ending up with a function object that does perfect forwarding, ending up with an actual function that does perfect forwarding. But the only way I can see of facilitating that would be factoring out the preprocessing code to make it easier for someone to implement one without code duplication. Best, Stjepan

Stjepan Rajko wrote:
On Dec 7, 2007 2:51 AM, Tobias Schwinger <tschwinger@isonews2.com> wrote:
Stjepan Rajko wrote:
* What is your evaluation of the implementation?
I agree with Dave on the EBO suggestion (and thanks for the compressed_pair lesson)
From my personal feeling inheriting from 'forward<F>' might be too rare of a use case to optimize for. However, with two reviewers asking for it I'll probably end up drowning my possibly premature assumptions on what the user will or will not do in a sea of genericity :-)...
I tend to be inheritance-happy :-)
:-). Nothing wrong with inheriting from it, I guess. I can imagine inheriting from it to improve error messages, for instance. However, for EBCO to pay off we have to both inherit from it and add more data members. It currently isn't really designed to have additional responsibilities added in subclasses, as a protected member function to access the decorated function object seems missing too in this context. Now with such a member (I think I'll add it), additional data needed in the derived class can probably put into the decorated function object - if not it becomes questionable whether the subclass' interface belongs into the same class as the base's.
Are there any arguments against implementing forward<F> using inheritance of (compressed_pair of) F?
If it ends up being never used we're adding unnecessary dependencies. If someone presents me a convincing use case I'll add it. Maybe I'll add it anyway, but I'd feel much better about it if someone did...
* What is your evaluation of the potential usefulness of the library?
Very useful. Although, I seem to run into cases where I want to have a forwarding function (not function object), or a forwarding operator. But maybe I'm wrong in preferring an actual function... Something like 'make_forward_adapter'?
You mean like 'make_fused', etc...? No, I meant instead of ending up with a function object that does perfect forwarding, ending up with an actual function that does perfect forwarding. But the only way I can see of facilitating that would be factoring out the preprocessing code to make it easier for someone to implement one without code duplication.
So we're talking about an overloaded function (not a function pointer)? Interesting. I doubt it's a good idea to promote duplication of 2**N overloads, except for very low N. Further, factoring our the preprocessing code seems like something I wouldn't want to do :-). Regards, Tobias

On Dec 9, 2007 2:54 AM, Tobias Schwinger <tschwinger@isonews2.com> wrote:
Stjepan Rajko wrote:
Are there any arguments against implementing forward<F> using inheritance of (compressed_pair of) F?
If it ends up being never used we're adding unnecessary dependencies.
OK.
If someone presents me a convincing use case I'll add it. Maybe I'll add it anyway, but I'd feel much better about it if someone did...
I don't know about convincing, but I'll give it a shot. I suppose the general category of use cases would be "forwarders with benefits", i.e., something that builds on the forwarding functionality and provides something extra on top of it. Here is a quickly thrown together example of a class that inherits forward_adapter to allow both immediate forwarding, as well as delayed forwarding ("delayed forwarding" = you call once to provide the arguments, and then call again to execute a call to the underlying function object using the previously stored arguments): http://pastebin.com/mcc92c4f I haven't really used this in practice, so it might be a highly contrived example.
You mean like 'make_fused', etc...? No, I meant instead of ending up with a function object that does perfect forwarding, ending up with an actual function that does perfect forwarding. But the only way I can see of facilitating that would be factoring out the preprocessing code to make it easier for someone to implement one without code duplication.
So we're talking about an overloaded function (not a function pointer)?
Interesting. I doubt it's a good idea to promote duplication of 2**N overloads, except for very low N. Further, factoring our the preprocessing code seems like something I wouldn't want to do :-).
When I first wrote the review, I started writing something along the lines of "it might be useful to factor out the preprocessing code", thought about it a little, and promptly erased it :-) Cheers, Stjepan

John Torjo wrote:
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
Boost.Functional/Forward provides decorator function objects to have an n-ary, generic function object accept both RValues and mutable LValues.
Sorry, this is not a review. Ignore this if irrelevant. Was boost::detail::functionN family in Boost.Accumulators considered? That seems more advanced than Boost.Functional/Forward. FWIW, starting from Abrahams' callable and functionN, I've been implementing a similar library: http://tinyurl.com/vd4r5 , which regards Boost.Functional/Forward facility as one of higher-order functions, `perfect`. BTW, IMHO, Boost.Functional/Forward seems not a good name, because C++0x has `std::forward` which takes not a function but argument! Regards, -- Shunsuke Sogame

on Fri Dec 07 2007, shunsuke <pstade.mb-AT-gmail.com> wrote:
John Torjo wrote:
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
Boost.Functional/Forward provides decorator function objects to have an n-ary, generic function object accept both RValues and mutable LValues.
Sorry, this is not a review. Ignore this if irrelevant.
Was boost::detail::functionN family in Boost.Accumulators considered? That seems more advanced than Boost.Functional/Forward.
FWIW, starting from Abrahams' callable and functionN, I've been implementing a similar library: http://tinyurl.com/vd4r5 , which regards Boost.Functional/Forward facility as one of higher-order functions, `perfect`.
Hmm. Did anyone reply to this? I think if someone points to an alternative library with that level of maturity during a review, it shouldn't be ignored. We should at least have a discussion of the relative merits of the two approaches before taking a vote. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
on Fri Dec 07 2007, shunsuke <pstade.mb-AT-gmail.com> wrote:
John Torjo wrote:
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
Boost.Functional/Forward provides decorator function objects to have an n-ary, generic function object accept both RValues and mutable LValues. Sorry, this is not a review. Ignore this if irrelevant.
Was boost::detail::functionN family in Boost.Accumulators considered? That seems more advanced than Boost.Functional/Forward.
FWIW, starting from Abrahams' callable and functionN, I've been implementing a similar library: http://tinyurl.com/vd4r5 , which regards Boost.Functional/Forward facility as one of higher-order functions, `perfect`.
Hmm. Did anyone reply to this? I think if someone points to an alternative library with that level of maturity during a review, it shouldn't be ignored. We should at least have a discussion of the relative merits of the two approaches before taking a vote.
I think the Egg library is awesome. Is it in the review queue yet? If not, it should be. My opinion here is that it can co-exist with the Forward library just as boost.bind can coexist with boost.lambda. It's not always a matter of which is more sophisticated. Certainly, bind is a subset of lambda. Yet, even with the simplicity of bind, it is sufficiently useful in many applications. I'd say the same for Egg and Boost.Functional. Let's have more FP in C++! :-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
David Abrahams wrote:
on Fri Dec 07 2007, shunsuke <pstade.mb-AT-gmail.com> wrote:
FWIW, starting from Abrahams' callable and functionN, I've been implementing a similar library: http://tinyurl.com/vd4r5 , which regards Boost.Functional/Forward facility as one of higher-order functions, `perfect`. Hmm. Did anyone reply to this? I think if someone points to an alternative library with that level of maturity during a review, it shouldn't be ignored. We should at least have a discussion of the relative merits of the two approaches before taking a vote.
I think the Egg library is awesome. Is it in the review queue yet? If not, it should be. My opinion here is that it can co-exist with the Forward library just as boost.bind can coexist with boost.lambda. It's not always a matter of which is more sophisticated. Certainly, bind is a subset of lambda. Yet, even with the simplicity of bind, it is sufficiently useful in many applications. I'd say the same for Egg and Boost.Functional.
Let's have more FP in C++! :-)
I've got to agree. The egg library looks like an incredible bit of work. I'd love to see this in Boost too. I for one though do find it confusing when there is overlap between libraries because normally the documentation of the libraries don't discus each other's strengths and weaknesses and why you might want to choose one over the other. That isn't to say that there shouldn't be overlap between libraries, but it would be nice if the documentation of the libraries cross tied a bit more. K -- http://www.kirit.com/

Kirit Sælensminde wrote:
Let's have more FP in C++! :-)
I've got to agree. The egg library looks like an incredible bit of work. I'd love to see this in Boost too.
If boosters think so, I could prepare it for review. It seems to take more time, though. BTW, I'm tempted to rename Egg to Boost.Functor.
I for one though do find it confusing when there is overlap between libraries because normally the documentation of the libraries don't discus each other's strengths and weaknesses and why you might want to choose one over the other.
That isn't to say that there shouldn't be overlap between libraries, but it would be nice if the documentation of the libraries cross tied a bit more.
I think this confusion sometimes comes from the fact that libraries don't define Concept names. "A FunctionObject that can be used with boost::bind" is not good. :-) Regards, -- Shunsuke Sogame

On 12/27/07, shunsuke <pstade.mb@gmail.com> wrote:
Kirit Sælensminde wrote:
Let's have more FP in C++! :-)
Boost will eventually reinvent the whole FC++ library (albeit with a more consistent boost feeling) :)
I've got to agree. The egg library looks like an incredible bit of work. I'd love to see this in Boost too.
Me too :). But I do not think this would make Boost.Forward useless. Egg is a complex libary that adds lot's of useful functionality to function objects, Forward instead is simply a small tool to allow a specific functionality. It is likely to be and remain much simpler than Egg, so it would be great to have both. If one day Egg really is found to obsolete the Forward library, Boost could simply remove it. It has happened before. There was a project to unify Boost.Bind and Boost.Phoenix which I do not know if it is still active nor at which stage it is. As there is a big overlap between Egg and Phoenix, Egg should integrate seamlessy with both libraries. Or maybe the easiest way would be to simply replace Phoenix (not a first class boost library).
If boosters think so, I could prepare it for review. It seems to take more time, though.
I think it needs at least a good tutorial.
BTW, I'm tempted to rename Egg to Boost.Functor.
What about Boost.Functional (already taken?) or Boost.FunctionAdapters, or, my favourite, Boost.FunctionObjectsOnSteroid :). Or just keep Egg, is simple and there is precendent for non descriptive names in boost.
[...] That isn't to say that there shouldn't be overlap between libraries, but it would be nice if the documentation of the libraries cross tied a bit more.
I think this confusion sometimes comes from the fact that libraries don't define Concept names. "A FunctionObject that can be used with boost::bind" is not good. :-)
I usually call them Polymorphic Function Objects, even if this also include FC++ (which originated the name), Boost.Lambda and Phoenix result type deduction protocols. IIRC the "official name" is AdaptableFunctionObject, even if I do not remember if the Boost.ResultOf documentation uses this name. Happy holidays, gpd

Giovanni Piero Deretta wrote:
There was a project to unify Boost.Bind and Boost.Phoenix which I do
Correction: Boost.Lambda and Phoenix.
not know if it is still active nor at which stage it is. As there is a
It will happen :) It's just that my priority now is Spirit2 release.
big overlap between Egg and Phoenix, Egg should integrate seamlessy with both libraries. Or maybe the easiest way would be to simply replace Phoenix (not a first class boost library).
Egg and Forward are more like building blocks. There's overlap, sure, but only at the core. Anyway, once I finally get the lambda merger going, I'd love to leverage more core libraries like Forward (and possibly even Egg). Then, Phoenix will give way to the new Lambda.
Happy holidays,
You too :-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

shunsuke wrote:
"A FunctionObject that can be used with boost::bind" is not good. :-)
It's much better than using cryptic Concept names in tutorial-style documentation, IMO. We have a bunch of Function object Concepts defined in Fusion - and I have to say I'm waiting for the day I can remove them IOW result type computation crutches are not needed anymore... Regards, Tobias

David Abrahams wrote:
on Fri Dec 07 2007, shunsuke <pstade.mb-AT-gmail.com> wrote:
John Torjo wrote:
Hi all,
The formal review of the Boost.Functional/Forward library, proposed by Tobias Schwinger, begins today :
Boost.Functional/Forward provides decorator function objects to have an n-ary, generic function object accept both RValues and mutable LValues. Sorry, this is not a review. Ignore this if irrelevant.
Was boost::detail::functionN family in Boost.Accumulators considered? That seems more advanced than Boost.Functional/Forward.
FWIW, starting from Abrahams' callable and functionN, I've been implementing a similar library: http://tinyurl.com/vd4r5 , which regards Boost.Functional/Forward facility as one of higher-order functions, `perfect`.
Hmm. Did anyone reply to this?
Yes, but for some odd reason my reply neither reached the list nor my 'Sent' folder (I probably missed a local error message).
I think if someone points to an alternative library with that level of maturity during a review, it shouldn't be ignored.
I certainly did not ignore it as I picked it up in another post: http://permalink.gmane.org/gmane.comp.lib.boost.user/32368
We should at least have a discussion of the relative merits of the two approaches before taking a vote.
I don't see a problem for "Egg" to use "Forward"... Regards, Tobias
participants (9)
-
David Abrahams
-
Giovanni Piero Deretta
-
Joel de Guzman
-
Joel de Guzman
-
John Torjo
-
Kirit Sælensminde
-
shunsuke
-
Stjepan Rajko
-
Tobias Schwinger