
Hi, While transforming and filtering sequences, it's pretty common to call the elements' member functions, so I think it's worth adding some syntactic sugar for range adaptors in order to achieve cleaner syntax. E.g. if we have a class struct Foo { std::string description() const; }; and we want to get all non-empty descriptions, we could just write this clean code: foo_list | transformed(&Foo::description) | filtered(&std::string::size) To enable this syntax, the attached patch should be applied to boost/range/adaptor/argument_fwd.hpp (diff against 1.47.0). Is there any interest to add this to Boost.Range? Thanks, Maxim

2011/10/12 Yanchenko Maxim <maximyanchenko@yandex.ru>
Hi,
While transforming and filtering sequences, it's pretty common to call the elements' member functions, so I think it's worth adding some syntactic sugar for range adaptors in order to achieve cleaner syntax.
E.g. if we have a class
struct Foo { std::string description() const; };
and we want to get all non-empty descriptions, we could just write this clean code:
foo_list | transformed(&Foo::description) | filtered(&std::string::size)
To enable this syntax, the attached patch should be applied to boost/range/adaptor/argument_fwd.hpp (diff against 1.47.0).
Is there any interest to add this to Boost.Range?
It doesn't seem all that onerous to insert a boost::mem_fn [1] in there (i.e., "transformed(boost::mem_fn(&Foo:::description))")...or does this not work? - Jeff [1] http://www.boost.org/doc/libs/1_47_0/libs/bind/mem_fn.html

Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung <at> gmail.com> writes:
While transforming and filtering sequences, it's pretty common to call the elements' member functions, so I think it's worth adding some syntactic sugar for range adaptors in order to achieve cleaner syntax.
foo_list | transformed(&Foo::description) | filtered(&std::string::size)
It doesn't seem all that onerous to insert a boost::mem_fn [1] in there (i.e., "transformed(boost::mem_fn(&Foo:::description))")...or does this not work?
Hi Jeff, Of course this works, as well as STL iterator-based loops versus BOOST_FOREACH. As I said, this is just a syntactic sugar that makes the code cleaner, and it does this for quite a frequent case when you call element's member function. Thanks, Maxim

On Wed, Oct 12, 2011 at 8:03 AM, Maxim Yanchenko <maximyanchenko@yandex.ru>wrote:
Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung <at> gmail.com> writes:
While transforming and filtering sequences, it's pretty common to call the elements' member functions, so I think it's worth adding some syntactic sugar for range adaptors in order to achieve cleaner syntax.
foo_list | transformed(&Foo::description) | filtered(&std::string::size)
It doesn't seem all that onerous to insert a boost::mem_fn [1] in there (i.e., "transformed(boost::mem_fn(&Foo:::description))")...or does this not work?
Hi Jeff,
Of course this works, as well as STL iterator-based loops versus BOOST_FOREACH.
I don't think that's a fair comparison at all.
As I said, this is just a syntactic sugar that makes the code cleaner, and it does this for quite a frequent case when you call element's member function.
I won't argue with you, it *does* simplify the code. And when you want to call a member function on the elements of a range, it *is* a pretty frequent use case (although one could also use statically-bound rather than dynamically-bound pointers-to-members). So these points I'm not disputing. I just wonder where you draw the line in supporting pointers-to-members directly. For example, should filtered also automatically wrap pointers-to-members? What about other Boost libraries parametrized on function objects? Thinking about it that way, I think, to avoid confusion about which interfaces support pointers-to-members directly and which don't, that, by default, none should (which seems to be pretty much the case now), and force the user to wrap using boost::mem_fn (or similar). And like I said earlier, is it all that onerous to insert a boost::mem_fn? Just doesn't seem like that big of a wart to me. - Jeff

On Wed, Oct 12, 2011 at 4:03 PM, Maxim Yanchenko <maximyanchenko@yandex.ru>wrote:
Hi Jeff,
Of course this works, as well as STL iterator-based loops versus BOOST_FOREACH. As I said, this is just a syntactic sugar that makes the code cleaner, and it does this for quite a frequent case when you call element's member function.
I'd like to see this patch make it into a release too, despite Jeff's misgivings. While I can appreciate Jeff's comments about consistency of Boost interfaces in different libraries, the Boost Range adaptors are absolutely all about brevity and clarity of exposition, and as such seem especially to benefit from this syntactic sugar. Is this patch's appearance in a release 'in progress'? Anyone? Thx, - Rob.

Boosters, I am considering my position on this patch. I can see that it is pleasant syntactic sugar, but the reason I consciously omitted this was that it suffers from combinatorial explosion. I feel that one of the nice aspects of the current Boost.Range design is that it reduces combinatorial explosion by breaking down items into their constituent orthogonal parts. However I am reconsidering since there are a growing number of people requesting this feature, and perhaps the pragmatic convenience outweighs the slightly theoretical design concern. I need to make some effort to tackle some of the Boost.Range suggestions that have been accumulating during a period of ill health. I apologize for slow responses. It is important, to me, to make interface changes that I do not later regret. This needs some further investigation and thought. Neil Groves On Fri, Mar 16, 2012 at 10:54 AM, Robert Jones <robertgbjones@gmail.com>wrote:
On Wed, Oct 12, 2011 at 4:03 PM, Maxim Yanchenko <maximyanchenko@yandex.ru>wrote:
Hi Jeff,
Of course this works, as well as STL iterator-based loops versus BOOST_FOREACH. As I said, this is just a syntactic sugar that makes the code cleaner,
and
it does this for quite a frequent case when you call element's member function.
I'd like to see this patch make it into a release too, despite Jeff's misgivings. While I can appreciate Jeff's comments about consistency of Boost interfaces in different libraries, the Boost Range adaptors are absolutely all about brevity and clarity of exposition, and as such seem especially to benefit from this syntactic sugar.
Is this patch's appearance in a release 'in progress'? Anyone?
Thx,
- Rob.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

I agree that adding overloads for member function pointers can cause combinatorial explosion. However, support could be added for member function pointers by adding a get_callable function, that would return the function object itself if its a function object, or return a wrapped function object for member function pointers. Then get_callable is called before passing the function to the iterator or algorithm. Then you can use a metafunction for the adaptors. So you would write this: transformed_range<R, typename result_of_get_callable<F>::type> instead of: transformed_range<R, F>
________________________________ From: Neil Groves <neil@grovescomputing.com> To: boost@lists.boost.org Sent: Friday, March 16, 2012 9:43 AM Subject: Re: [boost] [range] adaptors and member functions pointers
Boosters,
I am considering my position on this patch. I can see that it is pleasant syntactic sugar, but the reason I consciously omitted this was that it suffers from combinatorial explosion. I feel that one of the nice aspects of the current Boost.Range design is that it reduces combinatorial explosion by breaking down items into their constituent orthogonal parts.
However I am reconsidering since there are a growing number of people requesting this feature, and perhaps the pragmatic convenience outweighs the slightly theoretical design concern. I need to make some effort to tackle some of the Boost.Range suggestions that have been accumulating during a period of ill health. I apologize for slow responses. It is important, to me, to make interface changes that I do not later regret. This needs some further investigation and thought.
Neil Groves
On Fri, Mar 16, 2012 at 10:54 AM, Robert Jones <robertgbjones@gmail.com>wrote:
On Wed, Oct 12, 2011 at 4:03 PM, Maxim Yanchenko <maximyanchenko@yandex.ru>wrote:
Hi Jeff,
Of course this works, as well as STL iterator-based loops versus BOOST_FOREACH. As I said, this is just a syntactic sugar that makes the code cleaner,
and
it does this for quite a frequent case when you call element's member function.
I'd like to see this patch make it into a release too, despite Jeff's misgivings. While I can appreciate Jeff's comments about consistency of Boost interfaces in different libraries, the Boost Range adaptors are absolutely all about brevity and clarity of exposition, and as such seem especially to benefit from this syntactic sugar.
Is this patch's appearance in a release 'in progress'? Anyone?
Thx,
- Rob.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On Fri, Mar 16, 2012 at 6:43 AM, Neil Groves <neil@grovescomputing.com>wrote:
Boosters,
I am considering my position on this patch. I can see that it is pleasant syntactic sugar, but the reason I consciously omitted this was that it suffers from combinatorial explosion. I feel that one of the nice aspects of the current Boost.Range design is that it reduces combinatorial explosion by breaking down items into their constituent orthogonal parts.
However I am reconsidering since there are a growing number of people requesting this feature, and perhaps the pragmatic convenience outweighs the slightly theoretical design concern. I need to make some effort to tackle some of the Boost.Range suggestions that have been accumulating during a period of ill health. I apologize for slow responses. It is important, to me, to make interface changes that I do not later regret. This needs some further investigation and thought.
My unrequested opinion: First, I understand the motivation. However, I think it would be inconsistent and confusing if some libraries in Boost treated pointers-to-member-functions specially while others did not. And I don't see all of Boost moving to specially support pointers-to-member-functions. Also, the workaround is seriously really not so bad (explicitly wrapping with mem_fn), especially given C++'s general penchant for verbosity. My 2c, - Jeff

On Fri, Mar 16, 2012 at 6:56 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote:
On Fri, Mar 16, 2012 at 6:43 AM, Neil Groves <neil@grovescomputing.com>wrote:
Boosters,
I am considering my position on this patch. I can see that it is pleasant syntactic sugar, but the reason I consciously omitted this was that it suffers from combinatorial explosion. I feel that one of the nice aspects of the current Boost.Range design is that it reduces combinatorial explosion by breaking down items into their constituent orthogonal parts.
However I am reconsidering since there are a growing number of people requesting this feature, and perhaps the pragmatic convenience outweighs the slightly theoretical design concern. I need to make some effort to tackle some of the Boost.Range suggestions that have been accumulating during a period of ill health. I apologize for slow responses. It is important, to me, to make interface changes that I do not later regret. This needs some further investigation and thought.
My unrequested opinion: First, I understand the motivation. However, I think it would be inconsistent and confusing if some libraries in Boost treated pointers-to-member-functions specially while others did not. And I don't see all of Boost moving to specially support pointers-to-member-functions. Also, the workaround is seriously really not so bad (explicitly wrapping with mem_fn), especially given C++'s general penchant for verbosity.
Note that there is precedent in C++ for treating ptr-to-members and ptr-to-member functions specially, see for example the ConvertibleToFunction[1] concept employed by Adobe ASL library. Also, boost::bind (and std::bind) do treat them specially, not requiring mem_fn. Personally, I think it would be a great feature. -- gpd [1] http://stlab.adobe.com/group__concept__convertible__to__function.html

On Fri, Mar 16, 2012 at 1:33 PM, Giovanni Piero Deretta <gpderetta@gmail.com
wrote:
On Fri, Mar 16, 2012 at 6:43 AM, Neil Groves <neil@grovescomputing.com wrote:
Boosters,
I am considering my position on this patch. I can see that it is
syntactic sugar, but the reason I consciously omitted this was that it suffers from combinatorial explosion. I feel that one of the nice aspects of the current Boost.Range design is that it reduces combinatorial explosion by breaking down items into their constituent orthogonal
On Fri, Mar 16, 2012 at 6:56 PM, Jeffrey Lee Hellrung, Jr. <jeffrey.hellrung@gmail.com> wrote: pleasant parts.
However I am reconsidering since there are a growing number of people requesting this feature, and perhaps the pragmatic convenience outweighs the slightly theoretical design concern. I need to make some effort to tackle some of the Boost.Range suggestions that have been accumulating during a period of ill health. I apologize for slow responses. It is important, to me, to make interface changes that I do not later regret. This needs some further investigation and thought.
My unrequested opinion: First, I understand the motivation. However, I think it would be inconsistent and confusing if some libraries in Boost treated pointers-to-member-functions specially while others did not. And I don't see all of Boost moving to specially support pointers-to-member-functions. Also, the workaround is seriously really not so bad (explicitly wrapping with mem_fn), especially given C++'s general penchant for verbosity.
Note that there is precedent in C++ for treating ptr-to-members and ptr-to-member functions specially, see for example the ConvertibleToFunction[1] concept employed by Adobe ASL library.
Also, boost::bind (and std::bind) do treat them specially, not requiring mem_fn.
Personally, I think it would be a great feature.
-- gpd
[1] http://stlab.adobe.com/group__concept__convertible__to__function.html
I don't have a strong opinion either way; I'm certainly sympathetic to the syntactic convenience on the client side! Referring to [1]: incidentally, I too had been using a function in my internal algorithms and data structures that allowed function objects, pointers-to-members(-functions), and (yes, even) boost::reference_wrappers of the aforementioned to all be treated uniformly, and I ultimately felt that the uglification of the algorithms/data structures was worse than the improvement at the use of the algorithm/data structure. Plus it took extra documentation to justify the rationale for wrapping all my calls that would otherwise look like "f(x)" with "invoke(f)(x)". - Jeff
participants (7)
-
Giovanni Piero Deretta
-
Jeffrey Lee Hellrung, Jr.
-
Maxim Yanchenko
-
Neil Groves
-
paul Fultz
-
Robert Jones
-
Yanchenko Maxim