Boost logo

Boost :

Subject: Re: [boost] Formal Review: Boost.RangeEx
From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2009-02-25 12:13:11


On Wed, Feb 25, 2009 at 5:32 PM, Neil Groves <neil_at_[hidden]> wrote:
> Dear Giovanni,
>
> On Wed, Feb 25, 2009 at 4:21 PM, Giovanni Piero Deretta <gpderetta_at_[hidden]
>> wrote:
>
>> On Wed, Feb 25, 2009 at 5:00 PM, Neil Groves <neil_at_[hidden]>
>> wrote:
>> > Dear Sir,
>> >
>> > On Wed, Feb 25, 2009 at 3:36 PM, Rogier van Dalen <rogiervd_at_[hidden]
>> >wrote:
>> >
>> >> I am not sure I understand the motivation for the operator| syntax. Why
>> >> couldn't
>> >>        vec | boost::adaptors::reversed | boost::adaptors::unique
>> >> be written
>> >>        boost::adaptors::unique (boost::adaptors::reversed (vec))
>> >> ? I think this contrast would be fairer than what the documentation
>> >> currently has. Is there a reason why it is not possible to provide both
>> >> syntaxes? The pipe syntax is nice, but sort of restricts operations to 1
>> >> range in, 1 range out. Relatedly:
>> >>
>> >
>> > In the adaptors section the preference for operator| is documented. It
>> > simply chains better in my opinion.
>> >
>> > I do provide both alternatives, for example
>> >
>> > boost::make_uniqued_range(rng) is equivalent to rng | uniqued
>> >
>>
>> IMHO the make_... syntax for range adaptors is horrible (i don't even
>> like the past tense, why not just unique?).
>> But why use two different names in the first place? Why not make
>>
>
> I simply dislike lots of overloading particularly where the semantics are
> different. Perhaps the semantics aren't that different.

IMHO they are the same thing. I think of operator() in ' a | b' as
'b(a)', i.e as a generic apply operator.

>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.

<snip>
>>
>> 'some_functor(range) ' eqivalent to 'range | some_functor'
>>
>> (i would actually go for the syntax 'range | some_functor(_r)', where
>> _r is a placeholder for the range; This is usefull for adaptors that
>> actually have other parameters in addition to the range itself)
>>
>
> I would always prefer the '|' syntax to any normal function invocation
> however it is spelled. In my opinion, it combines much more elegantly.
>

I use the '|' syntax a lot when writing long pipelines because it
avoids long nested expressions (it also reads better left to right).
But when I need a simple map or filter before passing a range to an
algorithm I usually just go for the function call variant.

Also, if you have a range of ranges and want to map the nested ranges,
having 'transformed' as a function object becomes very useful:

range_of_ranges | transformed(transformed(f)));

(and BTW, what about renaming 'transformed' -> 'map' and 'filtered'
-> 'filter')

-- 
gpd

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