Boost logo

Boost :

From: shunsuke (pstade.mb_at_[hidden])
Date: 2008-04-11 06:45:25


Giovanni Piero Deretta wrote:
>> After all, I will follow Boost.Fusion (and other Boost libraries).
>> Ditto `X_` prefix.
>>
>
> the 'functional' namespace?

I don't know where typenames of function objects will be placed.
I will consult Dan Marsden.

>> I tend to think the way using ref is not so bad. :-)
>> `_1 < ref(m) && _2 < m` will be cumbersome in C++0x.
>
> Not sure what you means here.
> The syntax I had in mind was:
>
> lambda_ref[ _1 < m ]
>
> which would be the same as:
>
> lambda[ _1 < ref(m) ]
>
> or
>
> lambda[_1 < cref(m) ]
>
> i.e. it would do perfect forwarding.

I hear that
   `_1 < ref(m) && _2 < m`
will be:
   int m_ = m;
   [&m, m_](int a, int b){ return a < m && b < m_ };
in C++0x.
`m_` is needed to copy.
IMO, placeholder expression seems more beautiful than C++0x expression. :-p

>> I think only the outmost lazy function knows when *un*lambdification should be performed.
>
> I think that I still I haven't explained my self: you need to unlambda
> the immediate expression that uses placeholders. I want no Lambda, I
> just want to express simple generalized a-la FC++ currying using what
> just I have: boost.lambda.

FC++ currying slightly confuse me.
Again, that is not currying. :-(

>> After some thoughts,
>> "If has_sig_template is true, use Lambda protocol.
>> Otherwise, use ResultOf protocol."
>> may be a good solution.
>
> This is what I do in my result_of replacement and so far has worked flawlessy.

I will consult Daniel. IIRC, that patch needs some modifications.

> Another thing that bothers me with nestN is that it seems that there
> is an hard coded limit (i.e. the max N in _N_) on the number of
> nesting levels and also you have to specify the nesting level
> explictly instead of being implicit in the expression.

Right. It is a defect.

>> FWIW, nestN can be used with result_of,
>> because its expression contains only function-calls.
>
> You can express nested lambdas using curry.
> [I will keep using both the lambda[] syntax and optionally lazy
> functions because I find it more readable, just substitute it with
> 'unlambda' and apply magic 'lazy' pixie dust where necessary :)]
>
> let's define (in pseduo c++0x syntax var args and new function syntax).
>
> template<class F, class C>
> struct closure1 {
> F f;
> C c;
>
> template<typename Args...>
> auto operator ()(Args... args) -> decltype(f(c, args...)) {
> return f(c, args...);
> }
>
> };
>
> // this is actually a function object
> template<class F, class C>
> closure<F, C>
> close1(F f, C c) {
> closure<F, C> result = { f, c};
> return result;
> }

Egg uses this to implement curryN.
See: egg/detail/bind_left1.hpp.

> Now you can express this
>> auto always = lambda[ lambda(_a = _1 + 7)[ _1 ] ];
>
> as:
>
> auto always = lambda[ close1(lambda[ arg1 ], arg1) ];
>
> or, obviously,
>
> // another function object
> template<class F>
> auto curry1(F f) -> decltype(lambda[ close1(f, _1) ]) {
> return lambda[ close1(f, _1) ];
> }
>
> auto always = curry1( lambda[arg1] );
>
> or, just for the heck of it:
>
> auto always = lambda[ curry1(lambda[arg1])(arg1) ]; // needlessy convoluted

How about:
     auto always = close1(close1, _1);

> // more fun!
> auto always_the_sum = lambda[ curry1(lambda[arg1])(arg1 + arg2) ];
>
> auto always_10 = always_the_sum(4, 6);
>
> assert(always_10() == 10);

How about:
     auto always_the_sum = close1(close2, _1+_2);

> (functional programming is fun)
> BTW I've implemented the above with just an hour of work with lambda
> adaptors (with plain c++03) and it worked! The best thing is it is
> completely result_of compatible (you can express the type 'always'
> with result_of).
>
> You have clarified all my doubts on your library . I hope to write the
> final review done for tonight (spoiler: accepted modulo a mini review
> only for the documentation).

Thanks!

-- 
Shunsuke Sogame

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