
On 4/27/07, Peter Dimov <pdimov@mmltd.net> wrote:
Daniel Walker wrote:
[...]
_1 == _2 // ambiguous lambda::hold(_1) == _2 // lambda expression lambda::release(_1) == _2 // 3rd-party expression
I think that the right thing here (if we take the interoperability issue to heart) is to make
_1 == _2
"just work". It's an interesting challenge, but it's not impossible since that is exactly what is_bind_expression is intended to solve.
OK, I think you're bring up something new here with is_bind_expression that I haven't thought of yet. But first back to placeholders. _1 == _2 will "just work" as long as lambda is the only party overloading operator==. But if it's not, I don't understand how is_bind_expression would resolve the ambiguity. So, you mean the complete statement would be 'bind(f, _1 == _2);'? If _1 == _2 was unambiguous, and is_bind_expression were specialized for the functor generated by _1 == _2, then bind could treat its second argument as a subbind expression. However, back to your hypothetical, assuming that one day Boost.Bind provided delayed operator evaluation like lambda does now, and both bind's and lambda's operators are visible, and they're both using standard placeholders (or placeholders that specialize is_placeholder), then _1 == _2 is still ambiguous, right? If the idea is that Boost.Bind does *not* overload operators for placeholders, and lambda expressions can be treated as subbind expressions, then yeah, that's a great idea. But even if Boost.Bind doesn't overload operators for placeholders, there's still the issue of using lambda with 3rd-party libraries that do. I can't think of any examples right now, but they may very well start to emerge over the years. If an unrelated library overloads an operator for a placeholder, and it's used in a lambda expression, then both libraries break. So, I think there could still be a use for something like lamda::hold(_1) and lambda::release(_1). Actually, it may be a good idea to make these functions more general so that they could be used to resolve any operator overload ambiguities such as the one with Boost.Parameter where both it and lambda overload operator||, or some other combination of libraries where neither provide something similar to unlambda to remove their operator overloads from the compiler's overload list.
The next milestone, boost::bind( f, _1 + _2 ), is harder since it requires boost::bind to respect specializations of is_bind_expression.
Alright, you're getting me all excited about this idea. I've been trying to work one step at a time, first getting lambda to work with result_of (I have a cleaner/better implementation than my previously submitted patch that incorporates suggestions from the result_of discussion on this list), now I'm trying for TR1 placeholders and then I was going to look into TR1 bind. When I get to bind, I'll try to specialize is_bind_expression for lambda::lambda_functor<>, and I think this will work right away with GNU's TR1 since it already uses is_bind_expression. So, this may not be so far off. Incidentally, currying expressions like ... boost::bind<int>((_1 + _2 + _3), _1, _2, c)(a, b) ... should work as soon as lambda accepts TR1 placeholders. Right now you would have to write ... boost::bind<int>((lambda::_1 + lambda::_2 + lambda::_3), ::_1, ::_2, c)(a, b); Daniel