Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-04-28 11:43:11


On 4/27/07, Peter Dimov <pdimov_at_[hidden]> 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


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