
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