RE: [boost] Re: algorithms namespace

Stefan Slapeta wrote:
Pavol Droba wrote:
It is not really reasonable to await from a user to always type boost::algorithm::string::trim.
Maybe it could help a little bit to replace 'algorithm' by 'algo' and 'string' by 'str'.
IMHO, also shorter namespaces like 'boost::filesystem' have the problem of beeing too long to be used on every access. Long typenames like boost::filesystem::directory_iterator have a very high capability to make the code unreadable very quickly.
why not use: namespace sa = boost::algorithm::string; sa::trim( ... ); or namespace fs = boost::filesystem; fs::directory_iterator di = ...; Surely this gives you what you are after (shorter namespace names) without modifying the namespace currently used by the library (which will break existing code that uses the libraries). This is what namespace aliases are for and is used for the filesystem library in the regression test implementation. Regards, Reece _________________________________________________________________ It's fast, it's easy and it's free. Get MSN Messenger today! http://www.msn.co.uk/messenger

On Wed, Feb 18, 2004 at 05:23:29PM +0000, Reece Dunn wrote:
Stefan Slapeta wrote:
Pavol Droba wrote:
It is not really reasonable to await from a user to always type boost::algorithm::string::trim.
Maybe it could help a little bit to replace 'algorithm' by 'algo' and 'string' by 'str'.
IMHO, also shorter namespaces like 'boost::filesystem' have the problem of beeing too long to be used on every access. Long typenames like boost::filesystem::directory_iterator have a very high capability to make the code unreadable very quickly.
why not use: namespace sa = boost::algorithm::string; sa::trim( ... ); or namespace fs = boost::filesystem; fs::directory_iterator di = ...;
Surely this gives you what you are after (shorter namespace names) without modifying the namespace currently used by the library (which will break existing code that uses the libraries).
This is what namespace aliases are for and is used for the filesystem library in the regression test implementation.
Namespace aliasing is common practice, but the problem with the algorithm namespace lies elsewhere. If there would be just one boost::algorithm and everything inside it, than aliasing would work just fine. But imagine having namespace algo=boost::algorithm; namespace sa=boost::algorithm::string; namespace ca=boost::algorithm::container; It is easy to get lost in such a lot of namespace. One would have to look into the docs to see which algoritm lies in which namespace. It could realy be painful. Regards, Pavol

On Wed, 18 Feb 2004, Pavol Droba wrote:
If there would be just one boost::algorithm and everything inside it, than aliasing would work just fine. But imagine having
namespace algo=boost::algorithm; namespace sa=boost::algorithm::string; namespace ca=boost::algorithm::container;
It is easy to get lost in such a lot of namespace. One would have to look into the docs to see which algoritm lies in which namespace. It could realy be painful.
I think the subnamespaces are a bad idea. I suggest that #include <boost/algorithm/string.hpp> - Includes all string algorithms, in namespace boost::algorithm #include <boost/algorithm/container.hpp> - Includes all container algorithms, in namespace boost::algorithm #include <boost/algorithm.hpp> - Includes all boost/algorithm/* and imports them all into namespace "boost" with using declarations. Doug

Douglas Paul Gregor wrote:
On Wed, 18 Feb 2004, Pavol Droba wrote:
If there would be just one boost::algorithm and everything inside it, than aliasing would work just fine. But imagine having
namespace algo=boost::algorithm; namespace sa=boost::algorithm::string; namespace ca=boost::algorithm::container;
It is easy to get lost in such a lot of namespace. One would have to look into the docs to see which algoritm lies in which namespace. It could realy be painful.
I think the subnamespaces are a bad idea. I suggest that
#include <boost/algorithm/string.hpp> - Includes all string algorithms, in namespace boost::algorithm
#include <boost/algorithm/container.hpp> - Includes all container algorithms, in namespace boost::algorithm
#include <boost/algorithm.hpp> - Includes all boost/algorithm/* and imports them all into namespace "boost" with using declarations.
I am concerned about the name of an algorithm in the generalized boost::algorithm namespace not reflecting the fact that the algorithm refers to strings or containers. Of course I am aware that overloading will allow different algorithms which have the same name to refer to different objects, but still a fairly generalized name may not create a specific enough mnemonic for me, as an end-user, to be comfortable enough with, to know that the algorithm refers to string(s) or container(s). OTOH having the algorithm in the boost::algorithm::string or boost::algorithm::container namespace tells me that the algorithm is string-centric or container-centric, and then the generalized name for the algorithm bothers me less because I will always be invoking it by specifying the full namespace ( or namespace alias ) name. This is purely an aesthetic reaction, and the fact that I like generalized names for free-standing functions ( and function templates ) which reflect the action but specific namespaces which tell me to what the action might refer, more than I like generalized names in the same namespace referring to very different objects and actions upon them.

On Wed, Feb 18, 2004 at 05:07:02PM -0500, Edward Diener wrote:
Douglas Paul Gregor wrote:
On Wed, 18 Feb 2004, Pavol Droba wrote:
If there would be just one boost::algorithm and everything inside it, than aliasing would work just fine. But imagine having
namespace algo=boost::algorithm; namespace sa=boost::algorithm::string; namespace ca=boost::algorithm::container;
It is easy to get lost in such a lot of namespace. One would have to look into the docs to see which algoritm lies in which namespace. It could realy be painful.
I think the subnamespaces are a bad idea. I suggest that
#include <boost/algorithm/string.hpp> - Includes all string algorithms, in namespace boost::algorithm
#include <boost/algorithm/container.hpp> - Includes all container algorithms, in namespace boost::algorithm
#include <boost/algorithm.hpp> - Includes all boost/algorithm/* and imports them all into namespace "boost" with using declarations.
I am concerned about the name of an algorithm in the generalized boost::algorithm namespace not reflecting the fact that the algorithm refers to strings or containers. Of course I am aware that overloading will allow different algorithms which have the same name to refer to different objects, but still a fairly generalized name may not create a specific enough mnemonic for me, as an end-user, to be comfortable enough with, to know that the algorithm refers to string(s) or container(s). OTOH having the algorithm in the boost::algorithm::string or boost::algorithm::container namespace tells me that the algorithm is string-centric or container-centric, and then the generalized name for the algorithm bothers me less because I will always be invoking it by specifying the full namespace ( or namespace alias ) name. This is purely an aesthetic reaction, and the fact that I like generalized names for free-standing functions ( and function templates ) which reflect the action but specific namespaces which tell me to what the action might refer, more than I like generalized names in the same namespace referring to very different objects and actions upon them.
Actualy I don't realy think, that ambiguity is a big issue here. For instance, string algorithm library is not based on a specific string implementation, rather it works on any container with a reasonable properties. I expect the same from other parts of the algorithm library. An algorithm is an algorithm, it does not mather if it works on a string or on something else from the user perspective. So overloading is a natural way to solve the problem. Please give me an example of an algorithm, that can be threated differently for strings and for containers. If there would be something like that (I don't see any), than is would make sense to use different names, rather then just different namespace. Otherwise, a user can get quite confused. Just imagine, two functions with the same name, with the same arguments, both doing the different thing and the only difference is a namespace. It is not a good practice. So to conclude, I think, that putting everything into namespace algorithm is probably the best ide. And I'd like to support also the idea of importing all relevant names into "boost" namespace. Regards, Pavol

"Pavol Droba" <droba@topmail.sk> wrote in message news:20040219074546.GF11201@lenin.felcer.sk... [ambiguity not an issue]
Please give me an example of an algorithm, that can be threated differently for strings and for containers. If there would be something like that (I don't see any), than is would make sense to use different names, rather then just different namespace. Otherwise, a user can get quite confused.
The problem arise if there is, let's say, four versions of a particular algorithm. Two works on iterators and two works on containers and there might be other arguments too. It certainly clashes in the container algos so that we can't have unqualified calls but must use boost::XX and std::XX. br Thorsten

On Thu, Feb 19, 2004 at 07:37:38PM +1100, Thorsten Ottosen wrote:
"Pavol Droba" <droba@topmail.sk> wrote in message news:20040219074546.GF11201@lenin.felcer.sk... [ambiguity not an issue]
Please give me an example of an algorithm, that can be threated differently for strings and for containers. If there would be something like that (I don't see any), than is would make sense to use different names, rather then just different namespace. Otherwise, a user can get quite confused.
The problem arise if there is, let's say, four versions of a particular algorithm. Two works on iterators and two works on containers and there might be other arguments too. It certainly clashes in the container algos so that we can't have unqualified calls but must use boost::XX and std::XX.
Well, this is exatcly what I have pointed out. If there is such an ambiguity, that the names should be different. It could realy make some nasty problems, if you accidentialy use the wrong overload, just because you forget to specify the correct namespace. (For instance if you are using "using namespace" directive) I understand the current problem between std:: and boost:: algoritms. However, this problem is because, you are replacing the algorithms already defined in the std:: . And so the conflict pops up. I assume, that in boost::algorithm, most of the algorithms will use collection_traits of something similar, so there will no be a reason for the problems like this. Also, I doubt, that there will be an algorithm contained in two different algorithm libraries, just with a different signature. It should not be, by design. Regards, Pavol BTW: I just thought, when we are speaking about the algorithm namespace and libraries, It would make sense to consider if some libraries already contained in boost should not be moved to the algorithm namespace as well. For instance regex library might be a good candidate.

Thorsten Ottosen wrote:
"Pavol Droba" <droba@topmail.sk> wrote in message news:20040219074546.GF11201@lenin.felcer.sk... [ambiguity not an issue]
Please give me an example of an algorithm, that can be threated differently for strings and for containers. If there would be something like that (I don't see any), than is would make sense to use different names, rather then just different namespace. Otherwise, a user can get quite confused.
The problem arise if there is, let's say, four versions of a particular algorithm. Two works on iterators and two works on containers and there might be other arguments too. It certainly clashes in the container algos so that we can't have unqualified calls but must use boost::XX and std::XX.
I'm with Pavol here. One useful guideline is: "Do not overload a function if you care which overload would be called." In other words, functions with the same name should - roughly - have the same effect. They may differ in efficiency, const correctness, and so on, but the general effect should be the same. In other words, if I write replace(s, x, y), it should always replace all occurences of x in s with y and return the result (for example), no matter whether it's std::replace, str::replace, or cnt::replace. This is a guideline, not a rule. You can break it if you think the end result would be better without it. But if followed, it leads to code that is more readable and less error-prone.

Peter Dimov wrote:
Thorsten Ottosen wrote:
"Pavol Droba" <droba@topmail.sk> wrote in message news:20040219074546.GF11201@lenin.felcer.sk... [ambiguity not an issue]
Please give me an example of an algorithm, that can be threated differently for strings and for containers. If there would be something like that (I don't see any), than is would make sense to use different names, rather then just different namespace. Otherwise, a user can get quite confused.
The problem arise if there is, let's say, four versions of a particular algorithm. Two works on iterators and two works on containers and there might be other arguments too. It certainly clashes in the container algos so that we can't have unqualified calls but must use boost::XX and std::XX.
I'm with Pavol here. One useful guideline is: "Do not overload a function if you care which overload would be called." In other words, functions with the same name should - roughly - have the same effect. They may differ in efficiency, const correctness, and so on, but the general effect should be the same.
In other words, if I write replace(s, x, y), it should always replace all occurences of x in s with y and return the result (for example), no matter whether it's std::replace, str::replace, or cnt::replace.
This is a guideline, not a rule. You can break it if you think the end result would be better without it. But if followed, it leads to code that is more readable and less error-prone.
This was very much the point that I was making also. If one overloads too many functions with the same name in a single namespace, I believe it becomes confusing for the end user unless all of them are closely related to the same objects. That is why I was in favor of sectioning off boost string and boost container functions in their own boost::algorithm namespaces. As far as typing in long namespace names, aliases can alway be used. Finally I believe very strongly in sectioning off code into its own namespace. It creates much less headaches at the expense of possibly more typing, but this is a tradeoff I will always take. I believe it leads to much clearer code.

On Thu, Feb 19, 2004 at 10:37:19AM -0500, Edward Diener wrote: [snip]
I'm with Pavol here. One useful guideline is: "Do not overload a function if you care which overload would be called." In other words, functions with the same name should - roughly - have the same effect. They may differ in efficiency, const correctness, and so on, but the general effect should be the same.
In other words, if I write replace(s, x, y), it should always replace all occurences of x in s with y and return the result (for example), no matter whether it's std::replace, str::replace, or cnt::replace.
This is a guideline, not a rule. You can break it if you think the end result would be better without it. But if followed, it leads to code that is more readable and less error-prone.
This was very much the point that I was making also. If one overloads too many functions with the same name in a single namespace, I believe it becomes confusing for the end user unless all of them are closely related to the same objects. That is why I was in favor of sectioning off boost string and boost container functions in their own boost::algorithm namespaces.
As far as typing in long namespace names, aliases can alway be used.
Finally I believe very strongly in sectioning off code into its own namespace. It creates much less headaches at the expense of possibly more typing, but this is a tradeoff I will always take. I believe it leads to much clearer code.
You are arguing with a generic ideas. Well, there's nothing bad about them. There are few problems however. Every good idea turns bad if it gets missused. Sectioning is fine, until your reach a level when it takes more then it brings. Boost is already partitioned into several namespaces. Usualy there are 2 levels: "boost" and "boost::library_name". Now we are trying to add another level. IMHO it is starting to be too much. First of all, what would such a paritioning bring? I think, that the ambiguity problem is not a problem in the case of algorithms (it has been explained before). Current proposal tries to split namespace by the libraries. This partitioning is artificial and not related to any algorithms categories. For instance, many algorithms in the string algo library can be categorized as container algoritms (they work with containers) and vice versa. It is not sufficiently possible to draw a border line between these two, and what will happen if more algorithms will be added? I think, that such a hierarchy is useless, so there is not a good reason to use it. It might be possible to create some other hierarchy, but i doubt, that it will be any better. Regards, Pavol

On Wed, 18 Feb 2004, Pavol Droba wrote:
If there would be just one boost::algorithm and everything inside it,
would work just fine. But imagine having
namespace algo=boost::algorithm; namespace sa=boost::algorithm::string; namespace ca=boost::algorithm::container;
It is easy to get lost in such a lot of namespace. One would have to look into the docs to see which algoritm lies in which namespace. It could realy be
"Douglas Paul Gregor" <gregod@cs.rpi.edu> wrote in message news:20040218133129.U23746@eggbeater.cs.rpi.edu... than aliasing painful. I must admit that I haven't used quilified names that much since I prefer a using namespace XXX in my .cpp files. However, when overloaded versions cannot co-exist (because of ambiguity), I kind of like the idea of aliasing. I think with names like namespace str = boost::algorithm::string; namespace cont = boost::algorithm::container; One can always find the name that seems reasonable readable while still reasonable short.
I think the subnamespaces are a bad idea. I suggest that
#include <boost/algorithm/string.hpp> - Includes all string algorithms, in namespace boost::algorithm
#include <boost/algorithm/container.hpp> - Includes all container algorithms, in namespace boost::algorithm
#include <boost/algorithm.hpp> - Includes all boost/algorithm/* and imports them all into namespace "boost" with using declarations.
If it would work, I would like it. But I suspect that enable_if coding would be necessary to disambiguate overloaded functions. br Thorsten

On Thu, 19 Feb 2004, Thorsten Ottosen wrote:
"Douglas Paul Gregor" <gregod@cs.rpi.edu> wrote in message
#include <boost/algorithm/string.hpp> - Includes all string algorithms, in namespace boost::algorithm
#include <boost/algorithm/container.hpp> - Includes all container algorithms, in namespace boost::algorithm
#include <boost/algorithm.hpp> - Includes all boost/algorithm/* and imports them all into namespace "boost" with using declarations.
If it would work, I would like it. But I suspect that enable_if coding would be necessary to disambiguate overloaded functions.
Let's burn that bridge when we get there. I don't suspect it will be a problem. Doug

Thorsten wrote:
I must admit that I haven't used quilified names that much since I prefer a using namespace XXX in my .cpp files. However, when overloaded versions cannot co-exist (because of ambiguity), I kind of like the idea of aliasing. I think with names like
namespace str = boost::algorithm::string; namespace cont = boost::algorithm::container;
One can always find the name that seems reasonable readable while still reasonable short.
When I read someone's (my own or someone's else's code) I want to avoid going back (or too - horror - remember...) namespace aliasing from the top of the file. I.e., I want to be able to correctly read the types involved in a function. And, as Peter Dimov said (I think...), if you make a de facto standard of aliasing certain namespaces, such as "filesystem" into "fs", why not incorporate that scheme de legio... /David

On Wed, Feb 18, 2004 at 01:34:12PM -0500, Douglas Paul Gregor wrote:
On Wed, 18 Feb 2004, Pavol Droba wrote:
If there would be just one boost::algorithm and everything inside it, than aliasing would work just fine. But imagine having
namespace algo=boost::algorithm; namespace sa=boost::algorithm::string; namespace ca=boost::algorithm::container;
It is easy to get lost in such a lot of namespace. One would have to look into the docs to see which algoritm lies in which namespace. It could realy be painful.
I think the subnamespaces are a bad idea. I suggest that
#include <boost/algorithm/string.hpp> - Includes all string algorithms, in namespace boost::algorithm
#include <boost/algorithm/container.hpp> - Includes all container algorithms, in namespace boost::algorithm
#include <boost/algorithm.hpp> - Includes all boost/algorithm/* and imports them all into namespace "boost" with using declarations.
I like this idea. Seem clear enough. Regards, Pavol

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Reece Dunn | Sent: 18 February 2004 17:23 | To: boost@lists.boost.org | Subject: RE: [boost] Re: algorithms namespace | | | Stefan Slapeta wrote: | >Pavol Droba wrote: | > | >>It is not really reasonable to await from | >> a user to always type boost::algorithm::string::trim. | >> | > | >Maybe it could help a little bit to replace 'algorithm' by 'algo' and | >'string' by 'str'. | > | >IMHO, also shorter namespaces like 'boost::filesystem' have | the problem | >of | >beeing too long to be used on every access. Long typenames like | >boost::filesystem::directory_iterator have a very high | capability to make | >the code unreadable very quickly. | | why not use: | namespace sa = boost::algorithm::string; | sa::trim( ... ); | or | namespace fs = boost::filesystem; | fs::directory_iterator di = ...; | | Surely this gives you what you are after (shorter namespace | names) without | modifying the namespace currently used by the library (which | will break | existing code that uses the libraries). | | This is what namespace aliases are for and is used for the filesystem | library in the regression test implementation. | | Regards, | Reece Definitely, and also one can (and often should) write using boost::algorithm::string::trim; // etc using boost::filesystem::iterator; // Perhaps locally, if a more 'global' declaration might cause ambiguity problems. So I strongly oppose the use of abbreviated names. One of Boost's strengths is the refusal to use incomprehensible abbreviations. (Spare a thought too for what may be the majority of users - those whose first language is not english. Abbreviations won't appear in the dictionary.) Paul Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539 561830 +44 7714 330204 mailto: pbristow@hetp.u-net.com
participants (8)
-
David Bergman
-
Douglas Paul Gregor
-
Edward Diener
-
Paul A Bristow
-
Pavol Droba
-
Peter Dimov
-
Reece Dunn
-
Thorsten Ottosen