[bind][phoenix] unified placeholders, yea or nay?

I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance. I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would: 1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42. At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler-3 wrote
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance.
Bind should really not define _1, ... into the unamed namespace (IMO, this should be fixed in future Boost releases even if it will of course brake backward compatibility and existing code -- users can easily fix their existing code with using namespace boost::bind...). A part from that, why are Bind's placeholder confusing?
I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
Would it also complicate Bind compile-time errors?
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
What are the benefits of the unification? Thanks a lot. --Lorenzo -- View this message in context: http://boost.2283326.n4.nabble.com/bind-phoenix-unified-placeholders-yea-or-... Sent from the Boost - Dev mailing list archive at Nabble.com.

On 5/27/2012 4:35 PM, lcaminiti wrote:
Eric Niebler-3 wrote
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance.
Bind should really not define _1, ... into the unamed namespace (IMO, this should be fixed in future Boost releases even if it will of course brake backward compatibility and existing code -- users can easily fix their existing code with using namespace boost::bind...).
I am not proposing to change that.
A part from that, why are Bind's placeholder confusing?
They are not confusing in and of themselves. They are confusing when users include both phoenix and bind (perhaps indirectly), and find that references to _1 are ambiguous and need to be qualified.
I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
Would it also complicate Bind compile-time errors?
I don't believe it should.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
What are the benefits of the unification?
No more ambiguity errors. Phoenix and bind would share placeholders. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler-3 wrote
On 5/27/2012 4:35 PM, lcaminiti wrote:
Would it also complicate Bind compile-time errors?
I don't believe it should.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
What are the benefits of the unification?
No more ambiguity errors. Phoenix and bind would share placeholders.
This seems useful to me (especially if it does not come to the price of more complex Bind compiler errors). However, would the ambiguity also be resolved by moving Bind's placeholders out of the global namespace and have users do using namespace boost::bind... or using namespace boost::phoenix... explicitly? If so, which fix is better? Thanks. --Lorenzo -- View this message in context: http://boost.2283326.n4.nabble.com/bind-phoenix-unified-placeholders-yea-or-... Sent from the Boost - Dev mailing list archive at Nabble.com.

On 5/27/2012 8:26 PM, lcaminiti wrote:
Eric Niebler-3 wrote
On 5/27/2012 4:35 PM, lcaminiti wrote:
What are the benefits of the unification?
No more ambiguity errors. Phoenix and bind would share placeholders.
This seems useful to me (especially if it does not come to the price of more complex Bind compiler errors).
However, would the ambiguity also be resolved by moving Bind's placeholders out of the global namespace and have users do using namespace boost::bind... or using namespace boost::phoenix... explicitly? If so, which fix is better?
I am not proposing making any change that would break end-user code. I'm not necessarily opposed to that change, it's merely a separate discussion. If that's an issue that is important to you, please start a separate thread. Thanks, -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler-3 wrote
On 5/27/2012 8:26 PM, lcaminiti wrote:
Eric Niebler-3 wrote
On 5/27/2012 4:35 PM, lcaminiti wrote:
What are the benefits of the unification?
No more ambiguity errors. Phoenix and bind would share placeholders.
This seems useful to me (especially if it does not come to the price of more complex Bind compiler errors).
However, would the ambiguity also be resolved by moving Bind's placeholders out of the global namespace and have users do using namespace boost::bind... or using namespace boost::phoenix... explicitly? If so, which fix is better?
I am not proposing making any change that would break end-user code. I'm not necessarily opposed to that change, it's merely a separate discussion. If that's an issue that is important to you, please start a separate thread.
OK, I understand. On the unification work you are proposing, as I said, I'd find it useful. Thanks. --Lorenzo -- View this message in context: http://boost.2283326.n4.nabble.com/bind-phoenix-unified-placeholders-yea-or-... Sent from the Boost - Dev mailing list archive at Nabble.com.

Eric Niebler wrote:
2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?)
It's a precompiled header thing, if I recall correctly. Most precompiled header implementations didn't like variables. I'm not sure whether this is still an issue.

On 5/27/2012 7:22 PM, Eric Niebler wrote:
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance.
Is there not also a problem with boost::lambda using _n placeholders ? Or is this a non-problem because the end-user is expected to use either boost::lambda or boost::phoenix, but never both at the same time, since the latter is supposed to supercede the former ? I have always felt that none of these placeholders should have been lifted into the global namespace by default. An end-user can always do this for himself if he desires and then the often reported conflict with these placeholders is solved by not moving more than one of them into the global namespace. As for unification of these placeholders, if it can be done and made interoperable I think it is a worthy thing to do.

----- Original Message -----
From: Eric Niebler <eric@boostpro.com> To: Boost mailing list <boost@lists.boost.org> Cc: Sent: Sunday, May 27, 2012 7:22 PM Subject: [boost] [bind][phoenix] unified placeholders, yea or nay?
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance. I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
Perhaps, they could use the same placeholders in the C++11 standard library, as well.
-- Eric Niebler BoostPro Computing http://www.boostpro.com
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Eric Niebler wrote:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.)
Currently, Boost.Bind works on IBM XL C/C++ (formerly vacpp for visual age c++), while Boost.Proto does not. To be frank, the issue is that the name-lookup for templates of vacpp was never standard compliant, and IBM XL C/C++ just continued that "tradition", even after they started to add C++11 features. A single instance of such a name lookup problem is usually easy to "fix", but I can fully understand every developer that doesn't want to "fix" many places in his code for a non-compliant compiler to which he usually doesn't even have access.
2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?)
From a technical point of view, it should be possible to still support Boost.Bind on vacpp (IBM XL C/C++) . If you make the proposed change, could you ensure to fix all name lookup problems (for vacpp) in the parts of Boost.Proto on which Boost.Bind would depend? (Both IBM XL C/C++ for AIX, V12.1 and IBM XL C/C++ Enterprise Edition, V10.1 are part of the regular regression test runners for trunk, both still using vacpp as name)
Regards, Thomas

AMDG On 05/27/2012 04:22 PM, Eric Niebler wrote:
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance. I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
I think this is hard to do without breaking user code. Consider: using ::_1; boost::function<int(int)> f1; bind(f1, _1); // boost::bind ... using boost::phoenix::placeholders::_1; bind(std::plus<int>(), _1, _1); // boost::phoenix::bind Unifying ::_1 and boost::phoenix::placeholders::_1 has to break one of these unless boost::bind is also the same as boost::phoenix::bind. In Christ, Steven Watanabe

On 5/28/2012 7:56 PM, Steven Watanabe wrote:
AMDG
On 05/27/2012 04:22 PM, Eric Niebler wrote:
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance. I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
I think this is hard to do without breaking user code. Consider:
using ::_1; boost::function<int(int)> f1; bind(f1, _1); // boost::bind ... using boost::phoenix::placeholders::_1; bind(std::plus<int>(), _1, _1); // boost::phoenix::bind
Unifying ::_1 and boost::phoenix::placeholders::_1 has to break one of these unless boost::bind is also the same as boost::phoenix::bind.
Your point is about ADL not finding correct bind function, right? Yes, that's a problem I hadn't considered. Is it serious, in your opinion? I haven't formed an opinion yet. -- Eric Niebler BoostPro Computing http://www.boostpro.com

On 05/28/2012 01:22 AM, Eric Niebler wrote:
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance. I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
FWIW, phoenix should be able to use bind placeholder. In fact, phoenix can use any placeholder that specializes boost::is_placeholder. Couldn't we work off of that? For example, detect in the phoenix code wether the bind header has been included before? Issue a warning? error? Not sure ...

On 5/29/2012 3:35 PM, Thomas Heller wrote:
On 05/28/2012 01:22 AM, Eric Niebler wrote:
I'm considering taking on as a side project the unification of the bind and phoenix placeholders, a perennial source of confusion and annoyance. I hesitate before beginning because it necessarily introduces some complexity into boost.bind, a very small, simple, and light-weight library. In particular, the unification would:
1) Cause boost.bind to depend on boost.proto. (I would do what I could to keep that dependency as slight as possible.) 2) Could not be supported on all platforms; e.g. not on borland or (gcc < 4) where the placeholders are actually static inline functions(!). (Peter, is this an ODR thing?) 3) Would introduce Phoenix behaviors into Bind, insofar as _1 is a lambda such that _1(42) evaluates to 42.
At this point, it's not obvious to me that the benefits outweigh the costs. Opinions? Peter, I'd especially like to hear your thoughts.
FWIW, phoenix should be able to use bind placeholder. In fact, phoenix can use any placeholder that specializes boost::is_placeholder. Couldn't we work off of that? For example, detect in the phoenix code wether the bind header has been included before? Issue a warning? error?
ADL won't pickup phx functions and operators if the placeholders are in a different namespace unless they are tinged somehow with some proto/phx. _1 + _2 will not work if _1 and _2 are both totally oblivious of proto/phx. boost::is_placeholder is not enough. Regards, -- Joel de Guzman http://www.boostpro.com http://boost-spirit.com
participants (9)
-
Edward Diener
-
Eric Niebler
-
Joel de Guzman
-
lcaminiti
-
paul Fultz
-
Peter Dimov
-
Steven Watanabe
-
Thomas Heller
-
Thomas Klimpel