Boost logo

Boost :

From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2008-07-01 08:28:19


On Tue, Jul 1, 2008 at 12:50 PM, Dean Michael Berris
<mikhailberis_at_[hidden]> wrote:
> On Tue, Jul 1, 2008 at 6:22 PM, Giovanni Piero Deretta
> <gpderetta_at_[hidden]> wrote:
>> On Tue, Jul 1, 2008 at 7:12 AM, Dean Michael Berris
>> <mikhailberis_at_[hidden]> wrote:
>>>
>>> I think the point of using expression templates is to be able to do
>>> something like:
>>>
>>> copy( range(source) | taken(10) | map(mapper()),
>>> make_function_output_iterator(reducer()) // should have a better name?
>>> );
>>>
>>
>> You do not need anything more than what is in Lambda/Phoenix here.
>> Instead of having a different function for piping an generating views,
>> you use the same function and curry it:
>>
>> auto reduced = source | take(_, 10) | map(_, mapper()) | fold(_, reducer()) ;
>>
>> the _ is like _1 in bind/lambda/phoenix, but it doesn't make the whole
>> expression a lambda expression (it stops at one level). The pipe in
>> practice works like a compose operator. If you put the range at the
>> end, you wouldn't even need the '_' (just provide one less argument,
>> hey it is haskell :) ), but you give up variadic (or overloaded)
>> functions.
>>
>
> Isn't the whole point of creating an expression template
> based-approach to create these (maybe using proto I guess) and allow:
>
> 1. The same placeholders used in Phoenix+Proto to be used in the pipe
> syntax in range_ex (or an imaginary new RangeEx implementation).
> 2. Allow for efficient (i.e., compiler optimized/assisted)
> implementations of the composition of these new
> views/ranges/iterators.
>

Of course. My point is that you need very few beyond what is available
in Phoenix. Just the ability to have
a placeholder which doesn't make the whole expression lazy ( i.e.
foo(_) should be the same as unlambda(bind(foo, _1)) ).

> ?
>
> Although I do like how this looks granted that you are using C++0x's
> auto -- in today's C++, the reason I used the STL was to avoid having
> to compute the actual type produced by the pipe syntax.

You need to know the result type of the reducer even in your example,
so it is not specific to the 'sugared' syntax :)

> Maybe this is
> why Dave is asking for a better BOOST_TYPEOF. ;-)

Well, as long as the result type of the final fold has been
registered, it should work out of the box.

>
>>>
>>>> I think that the basic ranges that should (at least) be supported are:
>>>>
>>>> - mapped_range
>>>> - filtered_range
>>>> - taken_range (i.e. just the first n elements of a range)
>>>> - taken_while_range (i.e. the first elements such as a predicate is true)
>>>> - zipped_range
>>>> - unfold_range (with which you can pretty much express any other
>>>> range, see http://tinyurl.com/5mus25)
>>>>
>>>> An eventual 'drop' (take all the elements after the first n) and
>>>> 'drop_while' (drop the first elements such as a predicate is true)
>>>> probably need strict evaluation anyway and aren't worth supporting
>>>> explicitly.
>>>>
>>>
>>> I also think there should be a zipped_function which:
>>>
>>> - takes N function objects and an N-tuple
>>> - applies each function to the appropriate tuple
>>> - returns a tuple of results
>>
>> D'oh, of course, forgot this.
>> I think that zipped_range on top of zipped_iterator is enough, you
>> get the other functionality by composing with transformed_iterator.
>>
>
> Okay, but shouldn't this composition with transform_iterator be done
> with something that 'comes out of the box'?

It is ok to provide a zip+transform in a single function, but it is
not a primitive. Let's call it zip_with, its result type should be
transformed_range<zipped_range<RangeTuple> , Mapper>, we do not need
an explicit zippedWith_range (and in fact it would make deforestation
harder).

-- 
gpd

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