Removing Bind placeholders from the global namespace

This topic has again come up recently in boost-users. I have already assigned myself a ticket, https://svn.boost.org/trac/boost/ticket/2240 but have done nothing so far, in part because it would break other Boost libraries. (Patching placeholders.hpp is trivial in itself.) This is one case in which the trunk/release procedures don't work well as-is unless someone volunteers to produce a patch against all of Boost that at once moves the placeholders into namespace boost::placeholders _and_ fixes all errors that this would cause. It'd be easier to split the work: I put the breaking change in and then the libraries are fixed one by one. :-) Comments? -- Peter Dimov http://www.pdplayer.com

AMDG Peter Dimov wrote:
This topic has again come up recently in boost-users. I have already assigned myself a ticket,
https://svn.boost.org/trac/boost/ticket/2240
but have done nothing so far, in part because it would break other Boost libraries. (Patching placeholders.hpp is trivial in itself.)
This is one case in which the trunk/release procedures don't work well as-is unless someone volunteers to produce a patch against all of Boost that at once moves the placeholders into namespace boost::placeholders _and_ fixes all errors that this would cause.
It'd be easier to split the work: I put the breaking change in and then the libraries are fixed one by one. :-)
Comments?
Wouldn't it be possible to have the placeholders in both boost::placeholders and in the global namespace and deprecate the ones in the global namespace, so that the changes don't need to be made all at once? In Christ, Steven Watanabe

Steven Watanabe:
Wouldn't it be possible to have the placeholders in both boost::placeholders and in the global namespace and deprecate the ones in the global namespace, so that the changes don't need to be made all at once?
It would be possible, but I doubt that it would help. The libraries in general tend to not move away from deprecated functionality unless they break. So it might be better to just force the change.

On 13 Jun 2009, at 19:02, Peter Dimov wrote:
This topic has again come up recently in boost-users. I have already assigned myself a ticket,
https://svn.boost.org/trac/boost/ticket/2240
but have done nothing so far, in part because it would break other Boost libraries. (Patching placeholders.hpp is trivial in itself.)
One thought, which might effect this decision. I believe bind, with the current placeholders, is being placed into C+ +0x. This means version of boost with these placeholders in the global namespace are going to break programs that use: using namespace std; and their compiler's bind? Chris

Peter Dimov wrote:
This is one case in which the trunk/release procedures don't work well as-is unless someone volunteers to produce a patch against all of Boost that at once moves the placeholders into namespace boost::placeholders _and_ fixes all errors that this would cause.
This amounts to a breaking interface change. How would this situation have been better (or different) under the old system?
It'd be easier to split the work: I put the breaking change in and then the libraries are fixed one by one. :-)
easier than? I don't see any other way to do such a thing. That is though the work might be split up differently, the actual work seems to me to be exactly the same - and impossible to avoid with any kind of system. Robert Ramey

On Saturday 13 June 2009 22:02:27 Peter Dimov wrote:
This topic has again come up recently in boost-users. I have already assigned myself a ticket,
https://svn.boost.org/trac/boost/ticket/2240
but have done nothing so far, in part because it would break other Boost libraries. (Patching placeholders.hpp is trivial in itself.)
This is one case in which the trunk/release procedures don't work well as-is unless someone volunteers to produce a patch against all of Boost that at once moves the placeholders into namespace boost::placeholders _and_ fixes all errors that this would cause.
It'd be easier to split the work: I put the breaking change in and then the libraries are fixed one by one. :-)
Comments?
Will it break users' code that don't import boost::bind into the global namespace but use placeholders without qualification? If yes then, please, leave placeholders available as they are now. I have a plenty of code that follows this practice and it won't be easy to update.

Andrey Semashev wrote:
On Saturday 13 June 2009 22:02:27 Peter Dimov wrote:
This topic has again come up recently in boost-users. I have already assigned myself a ticket,
https://svn.boost.org/trac/boost/ticket/2240
but have done nothing so far, in part because it would break other Boost libraries. (Patching placeholders.hpp is trivial in itself.)
This is one case in which the trunk/release procedures don't work well as-is unless someone volunteers to produce a patch against all of Boost that at once moves the placeholders into namespace boost::placeholders _and_ fixes all errors that this would cause.
It'd be easier to split the work: I put the breaking change in and then the libraries are fixed one by one. :-)
Comments?
Will it break users' code that don't import boost::bind into the global namespace but use placeholders without qualification? If yes then, please, leave placeholders available as they are now. I have a plenty of code that follows this practice and it won't be easy to update.
From a user's point of view, I'd say having the user define a BOOST_BIND_USE_DEPRECATED_PLACEHOLDERS macro or something should be ok until the user manages to update their code. I also have code that would break with this change so this would be helpful.
Anyway, isn't boost::placeholders too presumptuous? It's not like any of the other libraries that use placeholders will be using these placholders. Unless they are! That would be sweet. -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani wrote:
Anyway, isn't boost::placeholders too presumptuous? It's not like any of the other libraries that use placeholders will be using these placholders. Unless they are! That would be sweet.
Agreed. Boost.Phoenix will have placeholders named _1, _2, etc. With some thought, we might be able to define these placeholders such that they can be shared across Bind, Phoenix, Spirit (Qi/Karma/Lex), xpressive, etc., and squish this placeholder issue for good. Making them Proto terminals would be a no-brainer except for the portability issues to ancient compilers. But now that we're breaking back-compat, it might be time to reconsider the Bind placeholder portability hacks. Anyway, sign me up for helping out with this one. I'd like to see a unified set of placeholders. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Sohail Somani wrote:
Anyway, isn't boost::placeholders too presumptuous? It's not like any of the other libraries that use placeholders will be using these placholders. Unless they are! That would be sweet.
Agreed. Boost.Phoenix will have placeholders named _1, _2, etc. With some thought, we might be able to define these placeholders such that they can be shared across Bind, Phoenix, Spirit (Qi/Karma/Lex), xpressive, etc., and squish this placeholder issue for good. Making them Proto terminals would be a no-brainer except for the portability issues to ancient compilers. But now that we're breaking back-compat, it might be time to reconsider the Bind placeholder portability hacks.
Anyway, sign me up for helping out with this one. I'd like to see a unified set of placeholders.
Sounds good to me. Seems all those libraries are going towards proto anyway. I bet you could do it all in a weekend with your eyes closed :-) -- Sohail Somani http://uint32t.blogspot.com

Peter Dimov wrote:
Sohail Somani:
Anyway, isn't boost::placeholders too presumptuous?
std::bind's placeholders are defined in namespace std::placeholders.
Those placeholders are really limited and as far as I can tell it would be tough to make them the foundation of anything except bind-like stuff. If you were to have (say) phoenix placeholders in boost::placeholders, you could still implement bind but the rest of the libraries could use the extra functionality. -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani:
Peter Dimov wrote:
Sohail Somani:
Anyway, isn't boost::placeholders too presumptuous?
std::bind's placeholders are defined in namespace std::placeholders.
Those placeholders are really limited and as far as I can tell it would be tough to make them the foundation of anything except bind-like stuff.
If you were to have (say) phoenix placeholders in boost::placeholders, you could still implement bind but the rest of the libraries could use the extra functionality.
That is all very well but doesn't make it quite clear to me what do you suggest. Not move bind's placeholders and leave them global? Move them to a namespace other than boost::placeholders? Something else entirely?

Peter Dimov wrote:
Sohail Somani:
Peter Dimov wrote:
Sohail Somani:
Anyway, isn't boost::placeholders too presumptuous?
std::bind's placeholders are defined in namespace std::placeholders.
Those placeholders are really limited and as far as I can tell it would be tough to make them the foundation of anything except bind-like stuff.
If you were to have (say) phoenix placeholders in boost::placeholders, you could still implement bind but the rest of the libraries could use the extra functionality.
That is all very well but doesn't make it quite clear to me what do you suggest. Not move bind's placeholders and leave them global? Move them to a namespace other than boost::placeholders? Something else entirely?
Sorry for not being clear! If the boost::placeholders namespace was to exist, I was suggesting that boost standardize on the placeholders in that namespace. This way, one can add "using namespace boost::placeholders" where there is a lot of binding going on and not worry about whether they should be using lambda's _1 or bind's _1 or phoenix arg1 or whatever else there is now. How many different placeholder libraries are there anyway? Hope that is a bit clearer. -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani:
If the boost::placeholders namespace was to exist, I was suggesting that boost standardize on the placeholders in that namespace.
OK, but what does this mean in the short term? What shoud we do with the immediate problem of bind's global placeholders?
This way, one can add "using namespace boost::placeholders" where there is a lot of binding going on and not worry about whether they should be using lambda's _1 or bind's _1 or phoenix arg1 or whatever else there is now.
This is unlikely. First, Lambda will probably not be converted to use placeholders other than its own. Second, once you have several competing libraries, you have to decide on the type of _1 + 1; it can't return both a Phoenix expression and a Lambda expression unless Phoenix expressions and Lambda expressions are interchangeable, in which case you basically have one library.

Peter Dimov wrote:
Sohail Somani:
If the boost::placeholders namespace was to exist, I was suggesting that boost standardize on the placeholders in that namespace.
OK, but what does this mean in the short term? What shoud we do with the immediate problem of bind's global placeholders?
I'd suggest a less "global" namespace to put them into. boost::bindns::placeholders ?
This way, one can add "using namespace boost::placeholders" where there is a lot of binding going on and not worry about whether they should be using lambda's _1 or bind's _1 or phoenix arg1 or whatever else there is now.
This is unlikely. First, Lambda will probably not be converted to use placeholders other than its own. Second, once you have several competing libraries, you have to decide on the type of _1 + 1; it can't return both a Phoenix expression and a Lambda expression unless Phoenix expressions and Lambda expressions are interchangeable, in which case you basically have one library.
I think by standardizing on proto, you have one representation but you could still have multiple implementations. Someone can correct me if I am wrong, which occurs often enough :-) -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani:
Peter Dimov wrote:
Sohail Somani:
If the boost::placeholders namespace was to exist, I was suggesting that boost standardize on the placeholders in that namespace.
OK, but what does this mean in the short term? What shoud we do with the immediate problem of bind's global placeholders?
I'd suggest a less "global" namespace to put them into. boost::bindns::placeholders ?
Well... and how does this achieve the goal of having "unified" placeholders in namespace boost::placeholders?

Peter Dimov wrote:
Sohail Somani:
Peter Dimov wrote:
Sohail Somani:
If the boost::placeholders namespace was to exist, I was suggesting that boost standardize on the placeholders in that namespace.
OK, but what does this mean in the short term? What shoud we do with the immediate problem of bind's global placeholders?
I'd suggest a less "global" namespace to put them into. boost::bindns::placeholders ?
Well... and how does this achieve the goal of having "unified" placeholders in namespace boost::placeholders?
Your question was what to do with the immediate problem of bind's global placeholders... That was what I was responding to. -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani:
Peter Dimov wrote:
Sohail Somani:
Peter Dimov wrote:
Sohail Somani:
If the boost::placeholders namespace was to exist, I was suggesting that boost standardize on the placeholders in that namespace.
OK, but what does this mean in the short term? What shoud we do with the immediate problem of bind's global placeholders?
I'd suggest a less "global" namespace to put them into. boost::bindns::placeholders ?
Well... and how does this achieve the goal of having "unified" placeholders in namespace boost::placeholders?
Your question was what to do with the immediate problem of bind's global placeholders... That was what I was responding to.
OK, let's try again. Why is moving Bind's placeholders to namespace boost::bindns::placeholders instead of namespace boost::placeholders better, in your opinion?

Peter Dimov wrote:
Sohail Somani:
Peter Dimov wrote:
Well... and how does this achieve the goal of having "unified" placeholders in namespace boost::placeholders?
Your question was what to do with the immediate problem of bind's global placeholders... That was what I was responding to.
OK, let's try again. Why is moving Bind's placeholders to namespace boost::bindns::placeholders instead of namespace boost::placeholders better, in your opinion?
Since you asked, in my opinion, it is better because it doesn't give the wrong impression that these are *the* boost placeholders and all those other libraries deliberately don't use them to make my life miserable :-) Though, thinking about it a bit further, if you were to annex the boost::placeholders namespace for bind's placeholders, maybe the other library authors would support what is in that namespace with their libraries. <hand_waving>How hard can it be?</hand_waving> I guess only they know. I am just asking for some assurance that boost::placeholders would not just be placeholders that work with one library forever. I think that is unfair to the user. There are some really great Boost libraries that help you make your code more concise and it isn't a coincidence that placeholders have a big part to play in these libraries. Patches welcome, I suppose. -- Sohail Somani http://uint32t.blogspot.com

AMDG Sohail Somani wrote:
Since you asked, in my opinion, it is better because it doesn't give the wrong impression that these are *the* boost placeholders and all those other libraries deliberately don't use them to make my life miserable :-)
Though, thinking about it a bit further, if you were to annex the boost::placeholders namespace for bind's placeholders, maybe the other library authors would support what is in that namespace with their libraries. <hand_waving>How hard can it be?</hand_waving> I guess only they know.
I am just asking for some assurance that boost::placeholders would not just be placeholders that work with one library forever. I think that is unfair to the user. There are some really great Boost libraries that help you make your code more concise and it isn't a coincidence that placeholders have a big part to play in these libraries.
Given that boost::bind is also at the top level, I don't see a problem with putting bind's placeholders in boost::placeholders. It should only require a few template specializations to make Lambda and Phoenix recognize them. The only issue is that as Peter mentioned, _1 + _1 won't work. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Sohail Somani wrote:
Though, thinking about it a bit further, if you were to annex the boost::placeholders namespace for bind's placeholders, maybe the other library authors would support what is in that namespace with their libraries. <hand_waving>How hard can it be?</hand_waving> I guess only they know.
Given that boost::bind is also at the top level, I don't see a problem with putting bind's placeholders in boost::placeholders. It should only require a few template specializations to make Lambda and Phoenix recognize them. The only issue is that as Peter mentioned, _1 + _1 won't work.
Why doesn't bind support the other placeholders instead? As you have indicated, they have more functionality. -- Sohail Somani http://uint32t.blogspot.com

On Jun 14, 2009, at 6:29 PM, Sohail Somani wrote:
Steven Watanabe wrote:
AMDG
Sohail Somani wrote:
Though, thinking about it a bit further, if you were to annex the boost::placeholders namespace for bind's placeholders, maybe the other library authors would support what is in that namespace with their libraries. <hand_waving>How hard can it be?</hand_waving> I guess only they know.
Given that boost::bind is also at the top level, I don't see a problem with putting bind's placeholders in boost::placeholders. It should only require a few template specializations to make Lambda and Phoenix recognize them. The only issue is that as Peter mentioned, _1 + _1 won't work.
Why doesn't bind support the other placeholders instead? As you have indicated, they have more functionality.
That would not create one canonical placeholder (type) /David

Peter Dimov wrote:
Sohail Somani:
Why doesn't bind support the other placeholders instead?
It does.
Through boost::is_placeholder<T>, I presume. That's reasonable. I still don't think that is enough to warrant mirroring std::placeholders in boost::placeholders. I don't think I have any more to say on the topic except what I have said so far. I guess you will know soon if I am the only one who feels this way :-) -- Sohail Somani http://uint32t.blogspot.com

Sohail Somani wrote:
Peter Dimov wrote:
Sohail Somani:
Why doesn't bind support the other placeholders instead? It does.
Through boost::is_placeholder<T>, I presume. That's reasonable. I still don't think that is enough to warrant mirroring std::placeholders in boost::placeholders.
I don't think I have any more to say on the topic except what I have said so far. I guess you will know soon if I am the only one who feels this way :-)
Here are my thoughts: * Put all common placeholders (i.e. we have _1... _N now) in boost::placeholders * Make them library agnostic (they don't even have to rely on boost.proto nor boost.bind) * Provide some necessary traits/functions for dealing with these placeholders. These should not be tied to any library (not proto, nor bind). boost::is_placeholder<T> is one such mechanism (what else?). Where is is_placeholder? if it is in boost.bind, it probably ought to be brought out on its own. _1 + _1 is slippery. This, IMO, cannot be a Phoenix nor Lambda, nor Bind expression. It has to be contaminated somehow to make it one. Bind has no problems with it, but I do not see any other solution at the moment for lambda and phoenix coexisting at the same time other than to allow them to keep their native placeholders in their own namespaces. Regards, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net

Joel de Guzman wrote:
_1 + _1 is slippery. This, IMO, cannot be a Phoenix nor Lambda, nor Bind expression. It has to be contaminated somehow to make it one. Bind has no problems with it, but I do not see any other solution at the moment for lambda and phoenix coexisting at the same time other than to allow them to keep their native placeholders in their own namespaces.
Here's how I see this: _1 + _1 is not a valid Bind expression AFAIK. It *is* a valid Lambda expression and a valid Phoenix expression. My recollection of the Phoenix review is that Phoenix would be Lambda2, and the old Lambda would be deprecated. So _1 + _1 is a Phoenix expression, and _1 is a Phoenix placeholder, and we leave lambda::_1 alone. Bind can be easily updated (via is_placeholder) to do the right thing. Sadly, that's not the end of things. If _1 is in the Phoenix domain such that _1 + _1 and _1 + 'a' are Phoenix function objects, then in what domain is a mixed expression such as _1 >> spirit::char_ (in principle ... I don't believe this is a valid Spirit parser, but you know what I mean)? It can't be *both* a Phoenix expression and a Spirit parser. One domain must dominate. And right now, Proto has no mechanism for choosing. Perhaps the idea of Grand Unified Placeholders is unimplementable in practice (I need to think more about this), but I do think that Bind and Phoenix can share placeholders, and that should eliminate 90% of all complaints going forward (once Lambda is good and deprecated). ... more rumination ... Is _1 == _2 a valid Bind expression? If so, and if we can make the semantics of such relational binds mean the same as the equivalent Phoenix expressions, then really, Phoenix is just an elaboration on Bind and these two libraries can still play nicely. I think. -- Eric Niebler BoostPro Computing http://www.boostpro.com

Eric Niebler wrote:
Perhaps the idea of Grand Unified Placeholders is unimplementable in practice (I need to think more about this), but I do think that Bind and Phoenix can share placeholders, and that should eliminate 90% of all complaints going forward (once Lambda is good and deprecated).
90% of complaints is better!
... more rumination ...
Is _1 == _2 a valid Bind expression? If so, and if we can make the semantics of such relational binds mean the same as the equivalent Phoenix expressions, then really, Phoenix is just an elaboration on Bind and these two libraries can still play nicely. I think.
The existing bind placeholders do not overload any operators. bind(...) == bind(...) is a valid bind expression though, iirc. Well I've used it, so it better be :-) Maybe another solution is to deprecate all the other bind/placeholder libs and suggest using Phoenix bind. That is, there is no point using any of the other libs besides "The Chosen Lib." Not sure that will work out too well though. -- Sohail Somani http://uint32t.blogspot.com

Joel de Guzman wrote:
Sohail Somani wrote:
Peter Dimov wrote:
Sohail Somani:
Why doesn't bind support the other placeholders instead? It does.
Through boost::is_placeholder<T>, I presume. That's reasonable. I still don't think that is enough to warrant mirroring std::placeholders in boost::placeholders.
I don't think I have any more to say on the topic except what I have said so far. I guess you will know soon if I am the only one who feels this way :-)
Here are my thoughts:
* Put all common placeholders (i.e. we have _1... _N now) in boost::placeholders * Make them library agnostic (they don't even have to rely on boost.proto nor boost.bind) * Provide some necessary traits/functions for dealing with these placeholders. These should not be tied to any library (not proto, nor bind). boost::is_placeholder<T> is one such mechanism (what else?). Where is is_placeholder? if it is in boost.bind, it probably ought to be brought out on its own.
I think this is what Peter was planning on doing. is_placeholder is independent of bind afaik.
_1 + _1 is slippery. This, IMO, cannot be a Phoenix nor Lambda, nor Bind expression. It has to be contaminated somehow to make it one. Bind has no problems with it, but I do not see any other solution at the moment for lambda and phoenix coexisting at the same time other than to allow them to keep their native placeholders in their own namespaces.
Have a chosen existing placeholder library put into boost::placeholders. I think this is the "worse is better" solution. Then have the libraries support these placeholders. I don't know how stuff like _1 >> some_other_proto_grammar_thingy would work. -- Sohail Somani http://uint32t.blogspot.com

On Monday 15 June 2009 02:22:22 Steven Watanabe wrote:
Given that boost::bind is also at the top level, I don't see a problem with putting bind's placeholders in boost::placeholders.
IMHO, that's not a good idea. If I'm not mistaken, the common tendency is to move libraries from the boost namespace into their own namespaces, and I embrace it. The boost::placeholders namespace indeed means something unified, not something that belongs solely to bind. Unless we have a Boost.Placeholders library, that is.
It should only require a few template specializations to make Lambda and Phoenix recognize them.
Great! I think, it would solve a lot of problems that led to this topic.
The only issue is that as Peter mentioned, _1 + _1 won't work.
I guess, in general it's not possible to interpret such expressions out of context. We could add a make_lambda function to explicitly construct a functional object out of a proto expression. Additionally, we could add member functions to boost::function in order to automatically interpret proto expressions as functional objects.

On Monday 15 June 2009 01:07:28 Peter Dimov wrote:
Andrey Semashev:
Will it break users' code that don't import boost::bind into the global namespace but use placeholders without qualification?
Yes it will. But we can't leave them as they're now because people complain of conflicts.
From other posts I got an impression that you are not planning to make these placeholders interchangeable between different libraries, such as bind and lambda. If so, then: * How does moving bind placeholders to boost::placeholders help? People have to qualify them now, they will still have to qualify them after the change. * Why boost::placeholders, if these placeholders will be specific to Boost.Bind? IMHO, if we're moving to unified placeholders (which is presumable the ultimate goal), this should be a major change to all involved libraries, namely, bind, lambda and phoenix at least. A backwards compatibility layer is a must for such a change, because the named libraries are the ones most frequently used. Moreover, I'd prefer if the old code compiled without a change by default (i.e. no BOOST_USE_GLOBAL_PLACEHOLDERS macro needed). I see another way of doing this. Perhaps, we could create a new functional library powered by proto that would accumulate features from bind, lambda and phoenix and release it independently. It could be designed the way we want and be targeted for recent compilers (IOW, drop hacks for ancient compilers). The old libraries would become deprecated, they won't change their interface a bit and will be left for compatibility. Maybe eventually these libraries will degenerate into a thin interface layers to the new library.

Andrey Semashev-2 wrote:
IMHO, if we're moving to unified placeholders (which is presumable the ultimate goal), this should be a major change to all involved libraries, namely, bind, lambda and phoenix at least. A backwards compatibility layer is a must for such a change, because the named libraries are the ones most frequently used. Moreover, I'd prefer if the old code compiled without a change by default (i.e. no BOOST_USE_GLOBAL_PLACEHOLDERS macro needed).
I see another way of doing this. Perhaps, we could create a new functional library powered by proto that would accumulate features from bind, lambda and phoenix and release it independently. It could be designed the way we want and be targeted for recent compilers (IOW, drop hacks for ancient compilers). The old libraries would become deprecated, they won't change their interface a bit and will be left for compatibility. Maybe eventually these libraries will degenerate into a thin interface layers to the new library.
I seem to recall a discussion a while back (possibly at the time of the Phoenix review) that mentioned the possibility of making boost::bind call through to phoenix::bind on supporting compilers and using the previous implementation on old/broken ones. That would then avoid the need for seperate placeholders on at least recent compilers. -- View this message in context: http://www.nabble.com/Removing-Bind-placeholders-from-the-global-namespace-t... Sent from the Boost - Dev mailing list archive at Nabble.com.
participants (10)
-
Andrey Semashev
-
Christopher Jefferson
-
David Bergman
-
Eric Niebler
-
Joel de Guzman
-
Peter Dimov
-
Richard Webb
-
Robert Ramey
-
Sohail Somani
-
Steven Watanabe