
On Wed, Feb 25, 2009 at 10:11 PM, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Vicente Botet skrev:
Dear Giovanni,
On Wed, Feb 25, 2009 at 5:13 PM, Giovanni Piero Deretta <gpderetta@gmail.com
wrote:
Yes, I think I might have over-emphasised the difference. Would you prefer the function overload to be in the boost::adaptors namespace, the boost namespace or something else?
I had considered creating a range adaptor to be highly different to applying an algorithm, perhaps I over-emphasised this distinction when making the decision.
FWIW, I have code like this:
total = ( r | filter(_r, f) | map(_r, m) | accumulate(_r, zero, a) );
i.e. I don't have a strong distinction between adaptor and algorithms.
Yes, I'm sold!
I agree, the introduction of the parameter (_r) makes the library homogeneus. An adaptor is a functor with a placeholder for the input parameter.
I my examples I removed the _r from the syntax. I don't see the point in having them, if the code can work without them. Are they really needed?
No, not necessarily: 1: transformed_range<...> r = transformed(range, f); 2: transformed_range<...> r = range | transformed(f); you could have the single argument variant of transformed (and in general the variant with arity N-1 of an adaptor) return 'something' that can function in a pipe. I would expect that 'something' to be a full fledged unary function object (the equivalent of bind(transformed, _1, f)) that can also work outside of pipes or even stored: boost::function<transformed_range<range_t, f_t>(range_t)> mapper = transformed(f); // or alternatively boost::result_of<mapper_t(f_t)>::type mapper = transformed(f); BOOST_FOREACH( v_t v, range | mapper) { ... } Which implies that transformed (and other adaptors) should store 'f' (and other parameters) by value (modulo boost::ref and friends). ( BTW If you decide to adopt this solution, I suggest putting the range parameter last. This way It would sort of simulate the automatic currying syntax of some functional languages (where omitting the last m parameters of n-arity function makes it a higher order function that returns an (n-m) arity function. ) This approach has unfortunately a big problem. If you have adaptors with optional arguments, without concepts it is an iteresting problem figuring out which overload the user wants: merged(r1, r2); // uses operator< as comparator merged(r1, r2, cmp); // uses cmp as comparator r1 | merged(r2, cmp); // interesting problem here! r1 | merged(_r, r2, cmp); // much better r2 | merged(r1, _r, cmp); // we have a choice of the argument to bind r1 ^merged(_r1, _r2, cmp)^ r2; // probably beyond the scope of the library ;) In my code, I use '_' as a placeholder, instead of '_r'. -- gpd