Re: [boost] Review Request: Introduction of boost::string namespace and string-conversion functions

Thank you all who replied so far. It is very much and truly appreciated. Tally for far 1. The idea in principle seems to be largely accepted. Phil Endecott raised a concern if the effort was not a wheel-reinvention due to string/number conversions in N2408. I feel N2408 does not have as broad scope and has serious limitations (no user-type conversions, no handling of any container<char>, etc.) 2. The name of the namespace. People largely seem content with "boost::string". Andrey Semashev expressed a concern that the name was too generic and could clash with std::string (using namespace boost; using namespace std). A fair point. However, I do not feel it is a boost::string "problem" per se but rather the "problem" with using-directives (or rather mis-using-directives). Using-directives beat the whole purpose on a namespace and best avoided (see Stroustrup 8.2.3). From my actual experience it was not an issue. Long time ago I've introduced aux::string in two sizeable projects and honestly did not have one single complain about name clashing. Bo Persson also expressed a concern siting it'll make it "very hard to propose the utilities for inclusion in a future language standard". May be. May be not. When things of that magnitude happen (which seem quite remote at present) components get moved from a namespace to a namespace (several times) anyway. Like some stuff from the "boost" namespace moving to the "tr1" namespace just ultimately to be moved to the "std" namespace. Therefore, unless something major comes up later we are settling on "boost::string". 3. Naming of the conversion functions. The "to/from/is" set seems to sit well with the majority of people. The to_string/from_string was floated around as alternatives. I feel that the "_string" extension indeed serves a mildly useful purpose when the "string" namespace is obfuscated. Like namespace boost::string obfuscated; string str = obfuscated::from(i); // What the...? string str = obfuscated::to_string(i); // Somewhat better but still... When used sensibly string str = boost::string::from(i); or namespace boost::string str; string str = str::from(i); the intention seems clear and the following feels like a tautology: string str = boost::string::to_string(i); Robert Stewart mentioned that "is" is a poor name choice. It doesn't imply "can convert to" and can be expensive to execute. Fair enough. I'll keep the name around as a placeholder for a rainy day. We might not need it at all if we agree on something along the following lines: // No throw, return default on failure, dunno if failed. int i = boost::string::to<int>(str, default_value); // No throw, return default on failure, can check if failed. boost::string::value i = boost::string::to<int>(str, default_value); if (i.good()) successfully converted 4. String-To-Something Conversion Interface. Considerable number of people were not exactly happy with my off the cuff int i = boost::string::to<int>(str)(default_value); Well, I do not like it either... I just like saying/suggesting things that I regret later. :-) I probably got carried away by the functional-chain-ability concept. The main reason (for me) it is not good is that it imposes the default-constructibility requirement. I think people on the original lexical_cast-realted thread were pretty content with int i = boost::string::to<int>(str, -1); syntax. If so, then we won't need int i = to(str).or_default(-1) int i = to(str, default_ = -1) Can we agree on the following interface: template<class T, class String> boost::string::value<T> boost::string::to(String const&, T const& =T()) throw(); The usage is // Does not throw, returns -1 on failure. Don't care if failed int i1 = boost::string::to<int>(str, -1); // Does not throw, returns -1 on failure. Care if failed boost::value<int> i2 = boost::string::to<int>(str, -1); if (i2.good()) successful conversion6. 5. Formatting with manipulators. I've implemented a prototype and it works just fine. string str = "0xFF"; int i1 = boost::string::to<int>(str, -1) >> std::hex; // returns 255 int i2 = boost::string::to<int>(str, -1)(std::hex); // Same as above For the time being I keep both interfaces (via () and >>). 6. Something-To-String Conversion Interface. That did not seem to generate much heat at all. I'll summarize to make sure we see it the same way: template<class T> boost::string::value<std::string> boost::string::from(T const&) throw(); Does not throw. No default value (do we need one?). Returns string() of failure. Usage: std::string s1 = boost::string::from(-1); // 'int' type deduced std::string s2 = boost::string::from<double>(-1); // 'double' type forced std::string s3 = boost::string::from(15) >> std::hex; // returns "0xF" if (s1.empty()) conversion failed boost::string::value<std::string> s4 = boost::string::from(-1); if (s4.good()) conversion succeeded 7. Check-Convertibility Interface. If we agree on the behavior above (using boost::string::value), then the separate boost::string::is does not seem needed. 8. Throw/No-Throw Behavior. You might have noticed that the interface above *never* throws anything on failure. I would like to highlight the fact (as it's different from lexical_cast behavior) and make sure people are happy with it. Those who need an exception thrown could do boost::value<int> i2 = boost::string::to<int>(str, -1); if (!i2.good()) throw something youself; Is it satisfactory? 9. Requested features. a) Handling any container<char> (Phil Endecott). I implemented a rough cut using boost::range and it handles std::(w)string, char/wchar_t const* with ease. To handle any container we might look into extending the interface with something like template<class T, class Range> boost::string::value<T> boost::string::to(Range const&, T const& =T()) throw(); I have not looked into it throughly yet though. b) Integration with Spirit (Hartmut Kaiser). My focus is currently on the interface. Then, we can look at Spirit+boost-string behind it as a separate issue as it requires Joel (and other Spirit developers) involved. c) locale. I have not looked into it at all and I am not sure I am well-qualified. OTOH I hope it'll fit into the proposed interface as string s3 = boost::string::from(15) >> std::hex >> locale-related-functionality; or string s3 = boost::string::from(15)(std::hex)(locale-related-functionality); If so, then we can return to the issue when we get all the above taken care of. Thanks, Vladimir.

Vladimir.Batov@[snip] wrote:
[snip]
Bo Persson also expressed a concern siting it'll make it "very hard to propose the utilities for inclusion in a future language standard". May be. May be not. When things of that magnitude happen (which seem quite remote at present)
Using boost::string makes inclusion in std even more distant, while choosing another name is trivial.
components get moved from a namespace to a namespace (several times) anyway. Like some stuff from the "boost" namespace moving to the "tr1" namespace just ultimately to be moved to the "std" namespace.
In most cases names does not change when moved to std::. The name 'boost::string' would suggest a string class for me, not a namespace. boost::strings, boost::text, boost::from_string/boost::to_string seems much better to me.
[snip]

Ilya Sokolov wrote:
In most cases names does not change when moved to std::. The name 'boost::string' would suggest a string class for me, not a namespace. boost::strings, boost::text, boost::from_string/boost::to_string seems much better to me.
I tend to agree on thinking of a string as a class. Given Vladimirs section-headers in his message,
3. Naming of the conversion functions. 4. String-To-Something Conversion Interface. 6. Something-To-String Conversion Interface. 7. Check-Convertibility Interface.
perhaps the namespace "convert" would be appropriate. Cheers, Rutger

Vladimir.Batov@wrsa.com.au wrote:
2. The name of the namespace.
People largely seem content with "boost::string".
[snip]
Therefore, unless something major comes up later we are settling on "boost::string".
Sorry, I still don't think that's a good idea. The problems that were mentioned seem quite real to me, whereas the namespace name can be easily changed to another one without problems. If boost::strings isn't good enough, there was another suggestion - to use the boost::algorithms namespace in the Boost.StringAlgorithms library. Actually, submitting these tools as the StringAlgorithms extension looks quite a viable idea to me.
3. Naming of the conversion functions.
The "to/from/is" set seems to sit well with the majority of people.
The to_string/from_string was floated around as alternatives. I feel that the "_string" extension indeed serves a mildly useful purpose when the "string" namespace is obfuscated. Like
namespace boost::string obfuscated;
string str = obfuscated::from(i); // What the...? string str = obfuscated::to_string(i); // Somewhat better but still...
I must say, this is my case. However, I tend to use acronyms for namespace aliases: namespace bll = boost::lambda; namespace bmi = boost::multi_index; As for this tool, I would probably namespace bsl = boost::string; Then the library usage becomes a mess.
When used sensibly
string str = boost::string::from(i);
That's too lengthy.
or namespace boost::string str; string str = str::from(i);
That's possible, however, str is often used as a variable name. I don't like the idea of messing it with the namespace alias.
the intention seems clear and the following feels like a tautology:
string str = boost::string::to_string(i);
Maybe that's another sign that the namespace name is suboptimal.
4. String-To-Something Conversion Interface.
I think people on the original lexical_cast-realted thread were pretty content with
int i = boost::string::to<int>(str, -1);
syntax. If so, then we won't need
int i = to(str).or_default(-1) int i = to(str, default_ = -1)
I think, "to<int>(str, -1)" does not exclude "to(str, default_ = -1)". I'd like to have both, especially since Boost.Parameter allows it. Then I could have: int i = to< int >(str, -1); int i = to< int >(str, default_ = -1); int i = to< int >(str, radix_ = 16); bool f = to< bool >(str, bool_alpha_ = true); int i = to< int >(str, locale_ = loc, default_ = 100);
6. Something-To-String Conversion Interface.
That did not seem to generate much heat at all. I'll summarize to make sure we see it the same way:
template<class T> boost::string::value<std::string> boost::string::from(T const&) throw();
Does not throw. No default value (do we need one?). Returns string() of failure.
I think, it should be symmetric to the "from-string" conversions and should have the same capabilities, including default values. See my suggestion above.
8. Throw/No-Throw Behavior.
You might have noticed that the interface above *never* throws anything on failure. I would like to highlight the fact (as it's different from lexical_cast behavior) and make sure people are happy with it. Those who need an exception thrown could do
boost::value<int> i2 = boost::string::to<int>(str, -1); if (!i2.good()) throw something youself;
Is it satisfactory?
Aside from symbol names, looks acceptable to me.

----- Original Message ----- From: "Andrey Semashev" <andrey.semashev@gmail.com> To: <boost@lists.boost.org> Sent: Friday, February 13, 2009 5:41 PM Subject: Re: [boost] Review Request: Introduction of boost::string namespace and string-conversion functions
Vladimir.Batov@wrsa.com.au wrote:
3. Naming of the conversion functions.
The "to/from/is" set seems to sit well with the majority of people.
The to_string/from_string was floated around as alternatives. I feel that the "_string" extension indeed serves a mildly useful purpose when the "string" namespace is obfuscated. Like
namespace boost::string obfuscated;
string str = obfuscated::from(i); // What the...? string str = obfuscated::to_string(i); // Somewhat better but still...
I must say, this is my case. However, I tend to use acronyms for namespace aliases:
namespace bll = boost::lambda; namespace bmi = boost::multi_index;
As for this tool, I would probably
namespace bsl = boost::string;
Not on your Boost.Log library doccumentation ;-) Cheers, Vicente

vicente.botet wrote:
I must say, this is my case. However, I tend to use acronyms for namespace aliases:
namespace bll = boost::lambda; namespace bmi = boost::multi_index;
As for this tool, I would probably
namespace bsl = boost::string;
Not on your Boost.Log library doccumentation ;-)
You got me nailed. :) The Boost.Log case is a bit special, since the docs have to be as clear as possible. And anyway, I didn't say I always do so.

Sorry, I still don't think that's a good idea.
There is nothing to be sorry about. Everyone has their convictions. That'd be naive of me to expect having you converted just one paragraph.
The problems that were mentioned seem quite real to me,
Yes, I understand... and I say you bring that problem onto yourself by sticking with bll, bsl, etc. I admit, it is convenient... but it just too limiting and will not work in the long run. Stop doing that and the problem will go away. BTW, with your naming schema how do you deal with Bost.Lambda and Boost.Log? ;-)
whereas the namespace name can be easily changed to another one without problems.
I am not sure how you can say "easily changed" if I want one thing and you want something else and somebody else might want something else again. There is no need to change the boost::string though (IMHO) as as-is it does not clash with *anything*. On the user level though every user can rename it to anything he finds sensible. I guess, you will have to find something more descriptive than 'bll', 'bsl'... namespace another_one_without_problems = boost::string; Therefore, IMHO the library name/namespace itself should be as descriptive as possible (and in this context boost::string is just that). Then, everyone will rename it to their liking.
If boost::strings isn't good enough, there was another suggestion - to use the boost::algorithms namespace in the Boost.StringAlgorithms library. Actually, submitting these tools as the StringAlgorithms extension looks quite a viable idea to me.
I am not saying "boost::strings isn't good enough". It just looks odd to me. I've never seen boost:lamdas, etc. And it does not clash with anything. And given I've been using aux::string with no problem the whole "clashing" argument does not stick with me. I feel that the whole name-"clashing" argument is misguided. The namespaces have been introduced exactly to avoid name clashes. So, that 'foo' in my namespace could live happily with 'foo' in your namespace. Therefore, the view that I cannot use 'foo' because it is already used in some other namespace just does not grow on me. And I am not exactly sympathetic to the cries like -- "look, I've opened up all the namespaces and now I have name clashes". As for the boost::algorithms namespace it's a completely different course. Dave suggested to start fresh. One of the steps would be to create a place for anything-string. I like the idea. So, I jumped in and I am prepared to stay that course trying to make it happen. For that I feel boost::string is perfect as tomorrow I can put some auxiliary string-class there (I already can thing of one) even though it's not an algorithm. Given our experience with lexical_cast I am weary of trying to submit anything as part of anything. Feel free to try.
3. Naming of the conversion functions.
namespace boost::string obfuscated;
I must say, this is my case. However, I tend to use acronyms for namespace aliases:
namespace bll = boost::lambda; namespace bmi = boost::multi_index;
As for this tool, I would probably
namespace bsl = boost::string;
And for Boost.Log you'll use ...? Just admit it on the smallest scale the strategy is OK. On a bigger scale it fails miserably. So, it won't work with Boost.Log and is not needed for Boost.String. Can you live with that?
Then the library usage becomes a mess.
No, the library does not become a mess -- your code becomes less readable. Is it *my* problem, you think? Or maybe, just maybe, it is poorly chosen namespace aliases?
string str = boost::string::from(i);
That's too lengthy.
You are teasing me, right? namespace bstring = boost::string; string str = bstring::from(i); string str = bstring::from_string(i); string str = bsl::from_string(i); Even with 'bsl' your version is longer. Then, what happened to your objectivity (if anything below looks familiar ;-) ): BOOST_LOG_DECLARE_GLOBAL_LOGGER_CTOR_ARGS(my_logger, src::logger_mt, (arg1)(arg2)(arg3)) pSink->locked_backend()->set_formatter(fmt::ostrm logging::core::get()->set_filter(flt::attr< severity_level >("Severity") >= warning); Just do not give me that Boost.Log is "special". :-)
the intention seems clear and the following feels like a tautology:
string str = boost::string::to_string(i);
Maybe that's another sign that the namespace name is suboptimal.
No, it is a sign that '_string' is redundant. Namespaces are similar the file hierarchy. Like "my-files/documents/letter". Given the hierarchy you expect 'letter" to be a document and to belong to me... without naming the file "my-letter-document". Similarly, I like boost::string::replace() boost::string::dedupe() boost::string::trim() Similarly to, say, boost::filesystem::exists() I am sure to find many other examples.
I think, "to<int>(str, -1)" does not exclude "to(str, default_ = -1)". I'd like to have both, especially since Boost.Parameter allows it. Then I could have:
int i = to< int >(str, -1); int i = to< int >(str, default_ = -1); int i = to< int >(str, radix_ = 16); bool f = to< bool >(str, bool_alpha_ = true); int i = to< int >(str, locale_ = loc, default_ = 100);
It does indeed look fancy. I'll look into it closer (to at the very least I'll deploy it *somewhere*). I have a few concerns though. 1) I need to be sure it does not impose default-constructibility requirement. 2) I am not sure it'll be more flexible than chaining like int i = boost::string::to(str, -1)(some-locale)(some-manipulator); as it seems to require to() to accept quite a few parameters. In other words, if I use them, I can run out of them. If I don't I pay the overhead price. 3) If one interface does what we need, why introduce an alternative. Choices often confuse people (they surely confuse me). Again, let me have a closer look at Boost.Parameter.
template<class T> boost::string::value<std::string> boost::string::from(T const&) throw();
I think, it should be symmetric to the "from-string" conversions and should have the same capabilities, including default values. See my suggestion above.
Makes sense. Will do. V.

On Fri, Feb 13, 2009 at 23:48, Vladimir Batov <batov@people.net.au> wrote:
I am not saying "boost::strings isn't good enough". It just looks odd to me. I've never seen boost:lamdas, etc.
The library's primary namespace (in parent ::boost) is given that same name, except when there's a component with that name (e.g., boost::tuple), in which case the namespace name is pluralized. For example, ::boost::filesystem. http://www.boost.org/development/requirements.html#Naming_consistency And perhaps you recall a small discussion about boost::uuids::uuid? :P I have a full response to the thread coming, but to tide you over while I'm typing, here's something overly cute that works in g++ 4.1.2 and I think is conforming: int i = 0; std::stringstream("1") >> i; std::cout << i << std::endl; std::stringstream("11") >> std::hex >> i; std::cout << i << std::endl; (std::stringstream("a") >> std::hex >> i) || (i = 2); std::cout << i << std::endl; (std::stringstream("a") >> i) || (i = 3); std::cout << i << std::endl; It gives, as expected: 1 17 10 3 Yes, I know it has lots of problems -- "1z" comes to mind -- but I enjoyed it. ~ Scott

Vladimir Batov wrote:
The problems that were mentioned seem quite real to me,
Yes, I understand... and I say you bring that problem onto yourself by sticking with bll, bsl, etc. I admit, it is convenient... but it just too limiting and will not work in the long run. Stop doing that and the problem will go away. BTW, with your naming schema how do you deal with Bost.Lambda and Boost.Log? ;-)
I haven't worked out a good practice with Boost.Log yet, but I think I'll settle with something as short as blog or blg. I'm not saying that everyone has to use this scheme, I'm just saying that I find it practical (I have applied it in quite a few projects to be able to say so). In response you advise me to drop this practice because you like your naming better. IMO, it doesn't work this way. One of the qualities of the submission is the ability to "look good" in the user's environment.
I am not saying "boost::strings isn't good enough". It just looks odd to me.
I believe, Scott has already pasted the link to the naming policies, so "strings" doesn't apply yet. That is, until you have a string class in your namespace.
And it does not clash with anything. And given I've been using aux::string with no problem the whole "clashing" argument does not stick with me.
How many people were using your aux::string? I don't think that as many as Boost users out there.
As for the boost::algorithms namespace it's a completely different course. Dave suggested to start fresh. One of the steps would be to create a place for anything-string. I like the idea. So, I jumped in and I am prepared to stay that course trying to make it happen. For that I feel boost::string is perfect as tomorrow I can put some auxiliary string-class there (I already can thing of one) even though it's not an algorithm. Given our experience with lexical_cast I am weary of trying to submit anything as part of anything. Feel free to try.
Ok, if you have additions on your mind that clearly don't fit into an algorithms library, I agree that Boost.StringAlgorithms is not appropriate.
You are teasing me, right?
namespace bstring = boost::string;
string str = bstring::from(i); string str = bstring::from_string(i); string str = bsl::from_string(i);
Even with 'bsl' your version is longer.
It is shorter than the original string str = boost::string::from(i); However, I'm not stick with the "from_string" name either. Other participants also suggested better names, like "parse" or "convert". The point is that this name alone brings you the understanding of what the function does. "from" does not.
Then, what happened to your objectivity (if anything below looks familiar ;-) ):
BOOST_LOG_DECLARE_GLOBAL_LOGGER_CTOR_ARGS(my_logger, src::logger_mt, (arg1)(arg2)(arg3)) pSink->locked_backend()->set_formatter(fmt::ostrm logging::core::get()->set_filter(flt::attr< severity_level >("Severity")
= warning);
Just do not give me that Boost.Log is "special". :-)
I don't think that this comparison is relevant in any way. Neither of these constructs is about parsing or formatting objects. Just to answer that, the closest thing to formatting in Boost.Log are formatters, which may look like this: fmt::ostrm << fmt::attr< int >("MyAttr"); Yes, it's longer, but it has completely different requirements and semantics. I don't want to go OT here, so if you have suggestions about Boost.Log, please, move to another thread.

... In response you advise me to drop this practice because you like your naming better.
No, I never said and I never meant that. If it came across that way , I apologize. I said, "it just too limiting and will not work in the long run",
How many people were using your aux::string? I don't think that as many as Boost users out there.
True. aux::string was limited to about two dozen people of various skill levels. Seemed like a good enough indication to me. Point taken though.
... Other participants also suggested better names, like "parse" or "convert". The point is that this name alone brings you the understanding of what the function does. "from" does not.
Yes, 'convert' is well worth considering. It might work both ways as well. Like string s = boost::string::convert(-1); // to string int i = boost::string::convert(str); // from string V.

Vladimir.Batov@wrsa.com.au wrote:
Tally so far
2. The name of the namespace.
People largely seem content with "boost::string".
Andrey Semashev expressed a concern that the name was too generic and could clash with std::string (using namespace boost; using namespace std). A fair point. However, I do not feel it is a boost::string "problem" per se but rather the "problem" with using-directives (or rather mis-using-directives). Using-directives beat the whole purpose on a namespace and best avoided (see Stroustrup 8.2.3). From my actual experience it was not an issue. Long time ago I've introduced aux::string in two sizeable projects and honestly did not have one single complain about name clashing.
Your counterarguments are not without merit but too easily dismiss the problem when choosing a different name could resolve them readily.
Bo Persson also expressed a concern siting it'll make it "very hard to propose the utilities for inclusion in a future language standard". May be. May be not. When things of that magnitude happen (which seem quite remote at present) components get moved from a namespace to a namespace (several times) anyway. Like some stuff from the "boost" namespace moving to the "tr1" namespace just ultimately to be moved to the "std" namespace.
Therefore, unless something major comes up later we are settling on "boost::string".
That's rather dismissive of the complaints. "text," "convert," and "conversion" seem at least as good as "string."
3. Naming of the conversion functions.
The "to/from/is" set seems to sit well with the majority of people.
I don't understand how you can claim that. Few commented for or against "is." As I recall the tally, excluding yourself, there was one that suggested "is" was fine and one (me) that said it wasn't. (You later note that you'll keep "is" as a placeholder pending further consideration, so I'm glad my concern isn't lost.) A number complained about "to" and "from." It didn't strike me that there was a majority favoring anything yet.
The to_string/from_string was floated around as alternatives. I feel that the "_string" extension indeed serves a mildly useful purpose when the "string" namespace is obfuscated. Like
Not just obfuscation, as you describe it, but also elimination by way of using directives or using declarations.
namespace boost::string obfuscated;
string str = obfuscated::from(i); // What the...? string str = obfuscated::to_string(i); // Somewhat better but still...
When used sensibly
string str = boost::string::from(i); or namespace boost::string str; string str = str::from(i);
the intention seems clear
Your notion of "sensible" use is not how all will use such functionality. Consider what can be extremely common: void f() { using boost::<something>::from; ... std::string s(from(i)); ... s = from(j); // etc. } "from" is not as meaningful. That name almost requires retaining the enclosing namespace or a namespace alias.
the following feels like a tautology:
string str = boost::string::to_string(i);
That only applies if both "string" and "to_string" are the selected names when finished.
Can we agree on the following interface:
template<class T, class String> boost::string::value<T> boost::string::to(String const&, T const& =T()) throw();
I'm not convinced. Naming is still an issue, of course, but this interface doesn't include the Boost.Parameters idea, for example.
6. Something-To-String Conversion Interface.
That did not seem to generate much heat at all. I'll summarize to make sure we see it the same way:
template<class T> boost::string::value<std::string> boost::string::from(T const&) throw();
Same answer.
Does not throw. No default value (do we need one?). Returns
If T is not restricted to built-ins, then there are many reasons why the conversion would fail. If the function is not to throw an exception, then there would need to be a default. (Imagine using this for input validation, which can set the stream state to fail when the validation fails.)
8. Throw/No-Throw Behavior.
You might have noticed that the interface above *never* throws anything on failure. I would like to highlight the fact (as it's different from lexical_cast behavior) and make sure people are happy with it. Those who need an exception thrown could do
boost::value<int> i2 = boost::string::to<int>(str, -1); if (!i2.good()) throw something youself;
Is it satisfactory?
Yes and no. Both approaches should be supported from the start. Getting an exception makes calling code simpler, but code that expects failures or that can't use or afford exceptions in some context would benefit from the non-throwing interface. Yes, others can add exceptions to the non-throwing version, but it would be better to include that in the library. The non-throwing version could be requested using overloading with std::nothrow_t.
9. Requested features.
a) Handling any container<char> (Phil Endecott). I implemented a rough cut using boost::range and it handles std::(w)string, char/wchar_t const* with ease. To handle any container we might look into extending the interface with something like
template<class T, class Range> boost::string::value<T> boost::string::to(Range const&, T const& =T()) throw();
I have not looked into it throughly yet though.
That is a wise direction to pursue. The string-oriented focus may be the problem with the namespace and function names. Perhaps this functionality be merged with the lexical_cast improvement ideas to create a general purpose type conversion facility. Instead of thinking about conversions to and from strings, think of those conversions as special cases of a more general type-to-type converter of which lexical_cast is a degenerate form. That suggests something like using "conversion" as the namespace name and replacing "to" and "from" with "convert." IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Your counterarguments are not without merit but too easily dismiss the problem when choosing a different name could resolve them readily.
1. If I wrote only a paragraph instead of a 3-volumes' analysis, it does not imply it was dismissed "too easily". 2. I sited that from my experience of actually having aux::string (for about 5years) it was not a problem once. 3. I indeed think that by cryptic aliasing Andrey brings the obfuscation problem onto himself. Still he is adamant to deploy this technique. In such a setting I feel he should be dealing with the consequences rather than me. 4. I'd expect it to be quite obvious (from this discussion) that *nothing* is resolved easily if more than one person involved.
Bo Persson also expressed a concern siting it'll make it ... Therefore, unless something major comes up later we are settling on "boost::string".
That's rather dismissive of the complaints.
I am not sure what you expected of me. I considered the complains. I counted how many complained (2) vs. how many replied but did not raise/see it as an issue (~5 with me). I provided summary and the result and moved on. What should I have done instead?
"text," "convert," and "conversion" seem at least as good as "string."
I am sure "text" will be as controversial. The other two are not good as the idea was to have a namespace for anything-string related and not just conversion. So, are you *actually* suggesting something else or just criticizing my "dismissive" style? Does your original "for boost::string" stand? :-)
The "to/from/is" set seems to sit well with the majority of people.
I don't understand how you can claim that.
I counted the number of people complaining and *not* complaining about any particular name. Then I compared the numbers. Then, I went with the bigger number.
... the tally, excluding yourself,
And you are excluding myself because...?
... A number complained about "to" and "from."
Again, I counted the numbers. I went with the bigger one and moved on. What am I missing?
It didn't strike me that there was a majority favoring anything yet.
Well, I am not sure how I can react to a nebulous "It didn't strike me". Should I recount? Do you have different numbers/names showing I cheated? Do you feel I rushed and should have waited longer?
The to_string/from_string was floated around as alternatives. I feel that the "_string" extension indeed serves a mildly useful purpose when the "string" namespace is obfuscated. Like
Not just obfuscation, as you describe it, but also elimination by way of using directives or using declarations.
Elimination *is* obfuscation. You strip me of my name and then complain that you find it hard to address me. Does it immediately become *my* problem?
namespace boost::string obfuscated;
string str = obfuscated::from(i); // What the...? string str = obfuscated::to_string(i); // Somewhat better but still...
When used sensibly
string str = boost::string::from(i); or namespace boost::string str; string str = str::from(i);
the intention seems clear
Your notion of "sensible" use is not how all will use such functionality.
It is *never* possible to please all.
Consider what can be extremely common:
void f() { using boost::<something>::from; ... std::string s(from(i)); ... s = from(j); // etc. }
"from" is not as meaningful. That name almost requires retaining the enclosing namespace or a namespace alias.
I find it hard arguing against examples like that. It is clearly a bad practice. The solution is *not* to deploy it. And the solution lies with the user. The expectation of messing something up and expecting someone else having to deal with it sounds infantile to me. If one sticks his fingers into an electrical socket and gets hurt, should we immediately replace it with a horse power? Then, that poor horse will be guilty of trampling somebody who jumped under its feet...
Can we agree on the following interface:
template<class T, class String> boost::string::value<T> boost::string::to(String const&, T const& =T()) throw();
I'm not convinced. Naming is still an issue, of course, but this interface doesn't include the Boost.Parameters idea, for example.
In other words, the interface *you* are suggesting is ... Without it it is hard to apply any metrics to such a broad range of opinions. We won't be able to please everyone. I'll go with the majority regardless it the minority is convinced or not.
6. Something-To-String Conversion Interface.
That did not seem to generate much heat at all. I'll summarize to make sure we see it the same way:
template<class T> boost::string::value<std::string> boost::string::from(T const&) throw();
Same answer.
I do not feel I can decisively act on your answer and need more information about what exactly you are proposing.
Does not throw. No default value (do we need one?). Returns
If T is not restricted to built-ins, then there are many reasons why the conversion would fail. If the function is not to throw an exception, then there would need to be a default. (Imagine using this for input validation, which can set the stream state to fail when the validation fails.)
Yes, I think it makes sense. template<class T> boost::string::value<std::string> boost::string::from(T const&, std::string const& =std::string()) throw(); Looks right?
8. Throw/No-Throw Behavior. ... Yes and no. Both approaches should be supported from the start. Getting an exception makes calling code simpler, but code that expects failures or that can't use or afford exceptions in some context would benefit from the non-throwing interface. Yes, others can add exceptions to the non-throwing version, but it would be better to include that in the library. The non-throwing version could be requested using overloading with std::nothrow_t.
I'll have to think about it. I do not like the "std::nothrow_t"-based solution as my usage-pattern is largely non-throwing. So, I do not want typing std::nothrow_t all the time.
... The string-oriented focus may be the problem with the namespace and function names. Perhaps this functionality be merged with the lexical_cast improvement ideas to create a general purpose type conversion facility. Instead of thinking about conversions to and from strings, think of those conversions as special cases of a more general type-to-type converter of which lexical_cast is a degenerate form. That suggests something like using "conversion" as the namespace name and replacing "to" and "from" with "convert."
The "lexical_cast improvement" was the original suggestion. It did not fly with many people (including the author and the maintainer). So, the decision's been made to start fresh. V.

On Fri, Feb 13, 2009 at 17:13, Vladimir Batov <batov@people.net.au> wrote:
I counted the number of people complaining and *not* complaining about any particular name. Then I compared the numbers. Then, I went with the bigger number.
I think that that form of comparison is unfair without stating ahead of time that you will be using it. It's perfectly plausible that people replying would not mention something that had already been brought up and not yet been addressed by the proposer. Regardless, a pure numerical count of first opinions is a poor method by which to decide something.
Elimination *is* obfuscation. You strip me of my name and then complain that you find it hard to address me. Does it immediately become *my* problem?
And yet you successfully used pronouns throughout that statement. Hopefully the library will also affect shortening where appropriate.

[snip]
brought up and not yet been addressed by the proposer. Regardless, a pure numerical count of first opinions is a poor method by which to decide something.
Elimination *is* obfuscation. You strip me of my name and then complain that you find it hard to address me. Does it immediately become *my* problem?
And yet you successfully used pronouns throughout that statement.
Scott, Having a few discussions between us :-) I'd honestly have expected a bit more from you. Essentially your email states "what you are doing is wrong... so wrong". Do you think it lifts my spirit to keep doing that or at least it helps me to find the "right" way to do that? Who needs lectures without suggestions? V.

On Fri, Feb 13, 2009 at 22:20, Vladimir Batov <batov@people.net.au> wrote:
Having a few discussions between us :-) I'd honestly have expected a bit more from you. Essentially your email states "what you are doing is wrong... so wrong". Do you think it lifts my spirit to keep doing that or at least it helps me to find the "right" way to do that? Who needs lectures without suggestions?
From the start, this thread has irked me, as including "review request" in the subject seems to flout the normal submission
To answer a rhetorical question with a rhetorical question, does it lift someones spirits to hear "Well, 5 people didn't explicitly reiterate your concern, so it must not be important"? A dozen-email exchange without a response from the thread author does not "People largely seem content [so] we are settling on boost::string" imply. It would have been easy to use "I'll stick with" instead of "we are settling on" to sound less domineering. I'd like to think that those discussions between us are evidence that each dissenting opinion should (ideally) be argued through to the end, as it may lead to important observations. It feels like you would like my comments on the thread, so I'll provide that. I didn't earlier as my objection was to form rather than technical aspects. Apologies if I re-tread ground unnecessarily. - Process process[1] for no apparent reason. You've mentioned having used a similar component many times, yet provided no "Preliminary submission". You appear to be holding the "Discuss, refine, resubmit. Repeat until satisfied" processes after the formal request, instead of before. One or the other could be "not as conventional", but both seems excessive. [1] http://www.boost.org/development/submissions.html - Concept You initially described the goal as follows: "My immediate interest/proposal in that namespace would be the string-conversion functionality. The basics of that functionality are currently handled by lexical_cast but need extended and unambiguously tagged as *string*-related conversions." My recollection is that lexical_cast was fine (or at least mostly acceptable) for conversion to strings, but conversion from strings was a much harder problem. Boost already has a library for that problem: Spirit. With Spirit2, in fact, my understanding is that it has a consistent way to both directions as well. (Arguably serialization does as well, but there any parsing is an implementation detail.) This makes it feel like the problem is already mostly solved, if in greater detail than this library actually calls for. That makes me think of another similar library, Bimap. Matias could have invented and implemented his own way of doing it, which may have provided the base functionality more quickly, but instead built on MultiIndex, ultimately getting a much more flexible library with less duplicated effort. The proposed library is essentially a very simple lexer and pretty-printer, so it feels like the right way to build it is using Spirit2 components in such a way that gradually increasing complexity in the conversions provide a path to something that could be extracted and used in a full spirit grammar, should requirements eventually surpass what the helper library provides. (Orders that progress from simple numeric IDs up to, many iterations later, a full DSL.) Unfortunately, I don't know enough about spirit2 to provide an outline of how this might look. Perhaps it would be a good idea to step back and decide on the boundaries for the functionality first. So far all I can tell is "string conversions allowing default values on failure and not needing default constructors". Does it allow formatting? Is this just for scalars? If it's for more, can I give different formatting for different elements of containers or structures? Where's the line where it gives up and says "use spirit"? Some major implementation issues will effect the interface, such as the choice of piggy-backing off operator<< or using a different method, so that's also important. - Names Prepositions make great language keywords, but as they're neither things, actions, nor descriptions, I hate the use of prepositions for identifiers. To and From are thus both inappropriate. Regardless, I find the current use of to/from confusing. to<int> and from<int> read equivalently, so there's no insight there. I think that in the context of the string namespace, the `to` function seems like it would have to convert *to* the entity implied by the context. Notably, std::bitset has a to_string function that gives the std::string corresponding to that bitset -- the opposite direction to the proposed use of `to`. Similarly, everyone that's used javascript, java, or .net has been exposed to ToString. I think, though, that the fact that a choice exists is just further proof that a preposition and a noun to not make a good name for an action; We want verbs. Spirit uses parse; Perhaps Spirit2 has already found a good verb for the pretty printer? The next in the big three is `is`. At least it's a verb, though I think it's the one that conveys the least information of any of them. To me, `to be` implies some sort of simultaneity, and all the uses of it I've seen have reflected that. A string is a string, not an int. Its contents may have a useful interpretation as an int, but that's a separate issue. For example, LLVM has an "isa<T>(x)" function[2] that performs a similar function to dynamic_cast<T*>(x)!=0. Similarly, VB.NET has a "typeof x is T" operator[3] for the same functionality. It also has a "x Is y" operator[4] for reference equality. All three use a far stronger state of being than "well, I can to some work to turn that into one of those". [2] http://llvm.org/docs/ProgrammersManual.html#isa [3] http://msdn.microsoft.com/en-us/library/ex56dsed.aspx [4] http://msdn.microsoft.com/en-us/library/kb136x1y.aspx can_parse_as<T> or similar seems like a plausible form for the name, though I don't really like it. I can't, however, think of a need to know this that wouldn't result in me wanting the parsed value. Check-then-parse seems almost certain to be wasteful -- particularly since I haven't seen any proposed code snippets that mention conversions other than int <-> string. (--syntax-only is of course useful in a compiler, but this library is not the right tool for anything close to that level of job.) [5] http://www.boost.org/doc/libs/1_38_0/libs/type_traits/doc/html/boost_typetra... (And that fact that I keep feeling obliged to put these names in `backticks` for clarity is further evidence that the name should be more explicit.) I think thats enough from me for now, ~ Scott

Scott, Thank you for your reply. Much appreciated. I was looking forward to that and you did not disappointed (on many levels) :-\.
To answer a rhetorical question with a rhetorical question, does it lift someones spirits to hear "Well, 5 people didn't explicitly reiterate your concern, so it must not be important"?
OK, you shot back at me with *your* rhetorical question. Can we leave it at that so that we can get to the technical side of things? Is it OK with you? :-)
A dozen-email exchange without a response from the thread author does not "People largely seem content [so] we are settling on boost::string" imply. It would have been easy to use "I'll stick with" instead of "we are settling on" to sound less domineering.
Yes, that'd have been easier if English was my native or I could borrow your head. "domineering"... aren't you reading too much into it? It is easy to forget that for a tiny minority of people English has not become native yet and, consequently, they tend to miss subtleties of the language. How 'bout you write a few words in Russian and we'll discuss it? I am sure you'll make a generous bunch of grammatical, linguistic, colloquial and cultural mistakes that I'll use to compile you character profile. It'll be fun.
It feels like you would like my comments on the thread, so I'll provide that. I didn't earlier as my objection was to form rather than technical aspects. Apologies if I re-tread ground unnecessarily.
Yes, I indeed found the technical part of your email very informative and I appreciate you sharing your thoughts on that (the technical part that is).
- Process
From the start, this thread has irked me, as including "review request" in the subject seems to flout the normal submission process[1] for no apparent reason.
"Flout", "domineering"... Do you think there is anything good still left in me? I'd probably better leave the group and go out to do my real evil things in the real evil world. Still, you are irked. So, this contemptuous, domineering me apologizes. As for the process, yes, it is unlikely I am following any particular process as I got to where I am mostly by accident. I was only hoping to get lexical_cast extended with default values (and no default-constructibility requirement) as I wanted something "standard" and lexical_cast seemed good for it and seemed to do almost all I needed. That turned out to be problematic with the author and the maintainer. So, there was a suggestion I go ahead and do it myself without looking at lexical_cast.
You've mentioned having used a similar component many times, yet provided no "Preliminary submission".
Yes, I consider nailing the interface an important step but more importantly I wanted to hear views like yours if there was a point/need of doing it at all. You obviously got irked I used the "review request" title. I did not know you were so sensitive to that. I'll use it sparingly from now on.
You appear to be holding the "Discuss, refine, resubmit. Repeat until satisfied" processes after the formal request, instead of before. One or the other could be "not as conventional", but both seems excessive.
Seems like no matter which way I go it turns out excessive. I seem to be such an excessive guy all of a sudden. :-)
- Concept
My recollection is that lexical_cast was fine (or at least mostly acceptable) for conversion to strings, but conversion from strings was a much harder problem.
It was not my reading. I considered to/from to be pretty symmetric with, say, formatting applied both ways, and the default values (people seem to want it even if I personally did not use/need the to-string default).
Boost already has a library for that problem: Spirit. With Spirit2, in fact, my understanding is that it has a consistent way to both directions as well. (Arguably serialization does as well, but there any parsing is an implementation detail.)
I am glad you brought it up. Something along these lines was nagging me as I was using boost::serialization for ultimately conversion to/from XML (i.e. string) and Hartmut mentioned Spirit capable of doing conversions. So, I was wondering if that my noise about conversion was not mis-guided. I played with Spirit (the parser part) only a little bit. I only managed to write a half-a-page parsing grammar just to happily replace it with a two-liner regular expression. Never looked back. Could you show how to convert int-to-string-to-int with Spirit? Can we apply hex/scientific/etc. formatting? Does it deal with user types (as lexical_cast does)?
This makes it feel like the problem is already mostly solved, if in greater detail than this library actually calls for.
Solved? That sounds very exciting and what I was hoping for. Again, could you jog a few lines how it's done? It'd be appreciated. It'd give me a kick-start what to look for in the Spirit documentation.
That makes me think of another similar library, Bimap. Matias could have invented and implemented his own way of doing it, which may have provided the base functionality more quickly, but instead built on MultiIndex, ultimately getting a much more flexible library with less duplicated effort.
I am not eager to waste my time doing something already available. I am sorry for being obtuse. Can I see a snippet how to do that? Then, I'll drop causing all that noise.
The proposed library is essentially a very simple lexer and pretty-printer, so it feels like the right way to build it is using Spirit2 components in such a way that gradually increasing complexity in the conversions provide a path to something that could be extracted and used in a full spirit grammar, should requirements eventually surpass what the helper library provides. (Orders that progress from simple numeric IDs up to, many iterations later, a full DSL.)
That sits very well with me.
Unfortunately, I don't know enough about spirit2 to provide an outline of how this might look.
Oh, bummer. So, no code in the end? Can anyone jump in and show us how to convert things with Spirit? Is it as inclusive as lexical_cast? I am really looking for someone to show me the right way. I could not apply Spirit to conversions I needed from the Spirit docs.
Perhaps it would be a good idea to step back and decide on the boundaries for the functionality first. So far all I can tell is "string conversions allowing default values on failure and not needing default constructors". Does it allow formatting? Is this just for scalars? If it's for more, can I give different formatting for different elements of containers or structures? Where's the line where it gives up and says "use spirit"? Some major implementation issues will effect the interface, such as the choice of piggy-backing off operator<< or using a different method, so that's also important.
The way we seemed to be heading (apart from the names) was string str = aux::string::from(-1, "0") >> std::hex; int i = aux::string::to(str, -1) >> std::hex; // Do not care to check the failure or aux::string::value<string> s = aux::string::from(-1) >> std::hex; aux::string::value<int> i = aux::string::to(str, -1) >> std::hex; if (s.good()) conversion successful if (i.good()) conversion successful Later that'd be extended to locales still following the same interface. Like string str = aux::string::from(false) >> some-how-stick-locale-here;
- Names
[snip] Yep, I got it -- you do not like "to/from" either. Did I get this right? (I seem to misinterpret things lately). ;-\ 'is' seems not needed with the interface above. So, at least we won't be arguing about it.
I think thats enough from me for now,
Yep, I think I've had just about enough of that stress as well. Off to fishing. I guess I'll read your thoughtful and considerate reply in two weeks. Then, I'll upload my implementation to the Vault to actually take it for a spin who interested... unless we figure out how Spirit does it for us. I'd really and honestly like to see it (too thick to figure it out myself). V.

Boost already has a library for that problem: Spirit. With Spirit2, in fact, my understanding is that it has a consistent way to both directions as well. (Arguably serialization does as well, but there any parsing is an implementation detail.)
I am glad you brought it up. Something along these lines was nagging me as I was using boost::serialization for ultimately conversion to/from XML (i.e. string) and Hartmut mentioned Spirit capable of doing conversions. So, I was wondering if that my noise about conversion was not mis-guided. I played with Spirit (the parser part) only a little bit. I only managed to write a half-a-page parsing grammar just to happily replace it with a two-liner regular expression. Never looked back.
Could you show how to convert int-to-string-to-int with Spirit? Can we apply hex/scientific/etc. formatting? Does it deal with user types (as lexical_cast does)?
namespace qi = boost::spirit::qi; namespace karma = boost::spirit::karma; int i = 0; if (qi::parse("1", int_, i)) karma::generate(outiter, int_, i); where outiter is some output iterator. 'int_' is only one of the available primitives, there are more: uint, long_, ulong, double_, float_, you get the picture. Full customization for special formats is provided, just write your own policies. Example: template <typename T> struct scientific_policy : karma::real_generator_policies<T> { // we want the numbers always to be in scientific format typedef karma::real_generator_policies<T> base_type; static int floatfield(T) { return base_type::scientific; } }; typedef karma::real_spec<double, scientific_policy<double> > science_type; double d = 1.2345; karma::generate(outiter, science_type(), d); which will generate: "1.234e00" (the default number of fractional digits is 3, but this can be changed easily as well). etc. the parse/generate functions are just one possible interface, another is to use iostream base manipulators: int i = 0; std::ci >> qi::match(int_, i); std::cout << karma::format(int_, i) << std::endl; HTH Regards Hartmut

Vladimir Batov wrote:
Rob Stewart wrote:
Your counterarguments are not without merit but too easily dismiss the problem when choosing a different name could resolve them readily.
1. If I wrote only a paragraph instead of a 3-volumes' analysis, it does not imply it was dismissed "too easily".
You snipped the text I quoted, but I was referring to the wording as much as to the conclusion. You've noted elsewhere that English is not your native language. Your name suggests that possibility, of course, but we have no way to know if we don't know you. I read what you wrote and cannot infer what you meant.
2. I sited that from my experience of actually having aux::string (for about 5years) it was not a problem once.
Your citation is of some value, but perhaps less than you think as you and those with whom you work comprise a small audience with certain usage patterns and don't necessarily reflect the wider audience.
3. I indeed think that by cryptic aliasing Andrey brings the obfuscation problem onto himself. Still he is adamant to deploy this technique. In such a setting I feel he should be dealing with the consequences rather than me.
I understand your point, yet you should consider alternatives that fit your notions but don't cause any more difficulty than necessary to others. The point, after all, is to maximize the audience of what you create, isn't it?
4. I'd expect it to be quite obvious (from this discussion) that *nothing* is resolved easily if more than one person involved.
Bo Persson also expressed a concern siting it'll make it ... Therefore, unless something major comes up later we are settling on "boost::string".
That's rather dismissive of the complaints.
I am not sure what you expected of me. I considered the complains. I counted how many complained (2) vs. how many replied but did not raise/see it as an issue (~5 with me). I provided summary and the result and moved on. What should I have done instead?
As has been noted, you arrived at your conclusion very soon after your initial post. Some folks that might be interested might have been on vacation, ill, busy, etc. Some might have simply lurked noting that another had voiced their concern. You had insufficient information and hadn't allowed enough time for consensus, so the conclusion you reached, and the language used -- there's that English issue again, of course -- lead to my comment. Just saying things like, "therefore, it seems as if most like,..." would describe your conclusion without peremptorily ending discussion.
"text," "convert," and "conversion" seem at least as good as "string."
I am sure "text" will be as controversial. The other two are not good as the idea was to have a namespace for anything-string related and not just conversion. So, are you *actually* suggesting something else or just criticizing my "dismissive" style? Does your original "for boost::string" stand? :-)
After seeing other concerns, and considering other issues, I became less enamored of boost::string. Conversion is not just limited to string to/from other things, so I'm inclined to think that it should be managed apart from an "anything string" namespace. It may be that boost::conversion::convert(...) is implemented in terms of boost::string::to/from, thus satisfying both. (I'm not advocating any names as yet, just using those as examples.)
The "to/from/is" set seems to sit well with the majority of people.
I don't understand how you can claim that.
I counted the number of people complaining and *not* complaining about any particular name. Then I compared the numbers. Then, I went with the bigger number.
This is, again, a problem of being too early. It is also a problem of counting all votes equally when some arguments are technical, others forward looking, and still others merely preference. Some concerns may merit more weight than others.
... the tally, excluding yourself,
And you are excluding myself because...?
It was your idea, so you're biased. If you're trying to evaluate the merit of your idea, it seems misleading to count your own vote in its favor.
... A number complained about "to" and "from."
Again, I counted the numbers. I went with the bigger one and moved on. What am I missing?
As before.
It didn't strike me that there was a majority favoring anything yet.
Well, I am not sure how I can react to a nebulous "It didn't strike me". Should I recount? Do you have different numbers/names showing I cheated? Do you feel I rushed and should have waited longer?
I wasn't accusing you of cheating, but operating upon too few samples to arrive at a statistically significant conclusion.
The to_string/from_string was floated around as alternatives. I feel that the "_string" extension indeed serves a mildly useful purpose when the "string" namespace is obfuscated. Like
Not just obfuscation, as you describe it, but also elimination by way of using directives or using declarations.
Elimination *is* obfuscation. You strip me of my name and then complain that you find it hard to address me. Does it immediately become *my* problem?
I disagree that it is obfuscation. In one context, referring to me as "Dad" is perfectly clear. In another, "Rob" is appropriate. In yet another, more of my name is needed. I've never had the problem you suggest with names from any other namespace. There can be a question of which type or function is meant when there is more than one namespace providing that name, but when there is ambiguity the compiler requires scope resolution anyway. Otherwise, I've found names to work well without namespace scope. Yours are the first I've encountered to the contrary suggesting they could be improved.
Your notion of "sensible" use is not how all will use such functionality.
It is *never* possible to please all.
I wasn't suggesting that you should try to do so. However, using directives *are* common, even if not in your code.
Consider what can be extremely common:
void f() { using boost::<something>::from; ... std::string s(from(i)); ... s = from(j); // etc. }
"from" is not as meaningful. That name almost requires retaining the enclosing namespace or a namespace alias.
I find it hard arguing against examples like that. It is clearly a bad practice. The solution is *not* to deploy it. And the solution lies with the user. The expectation of messing something up and expecting someone else having to deal with it sounds infantile to me.
Wow! I thought we were being reasonable until this point. Apparently, I'm a horrible developer and clearly do bad things. In case my sarcasm isn't obvious, I do not accept your criticism of what I showed in the example. It *is not* bad practice.
Can we agree on the following interface:
template<class T, class String> boost::string::value<T> boost::string::to(String const&, T const& =T()) throw();
I'm not convinced. Naming is still an issue, of course, but this interface doesn't include the Boost.Parameters idea, for example.
In other words, the interface *you* are suggesting is ...
I don't yet understand the entire scope, so I can hardly suggest alternatives.
Without it it is hard to apply any metrics to such a broad range of opinions. We won't be able to please everyone. I'll go with the majority regardless it the minority is convinced or not.
The right design is right whether the majority agrees, at least at first, or not.
6. Something-To-String Conversion Interface.
That did not seem to generate much heat at all. I'll summarize to make sure we see it the same way:
template<class T> boost::string::value<std::string> boost::string::from(T const&) throw();
Same answer.
I do not feel I can decisively act on your answer and need more information about what exactly you are proposing.
I cannot say more without a better understanding of the short and long term goals. As you have submitted your request for a formal review already, I wonder why I'm taking the time to respond to any of this.
Does not throw. No default value (do we need one?). Returns
If T is not restricted to built-ins, then there are many reasons why the conversion would fail. If the function is not to throw an exception, then there would need to be a default. (Imagine using this for input validation, which can set the stream state to fail when the validation fails.)
Yes, I think it makes sense.
template<class T> boost::string::value<std::string> boost::string::from(T const&, std::string const& =std::string()) throw();
Looks right?
Maybe
The string-oriented focus may be the problem with the namespace and function names. Perhaps this functionality be merged with the lexical_cast improvement ideas to create a general purpose type conversion facility. Instead of thinking about conversions to and from strings, think of those conversions as special cases of a more general type-to-type converter of which lexical_cast is a degenerate form. That suggests something like using "conversion" as the namespace name and replacing "to" and "from" with "convert."
The "lexical_cast improvement" was the original suggestion. It did not fly with many people (including the author and the maintainer). So, the decision's been made to start fresh.
Yes, but you have an opportunity to create a new, general purpose conversion framework that does more than just conversions to and from string, with the latter merely a special case. Instead of retrenching from lexical_cast to nothing but conversions to/from strings, I'm suggesting a wider scope. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

Robert, Apologies for snipping the rest of your post. The thing is I agree with all you say, the reason I am replying to the snippet below is to try to explain myself. Best, V.
Consider what can be extremely common:
void f() { using boost::<something>::from; ... std::string s(from(i)); ... s = from(j); // etc. }
"from" is not as meaningful. That name almost requires retaining the enclosing namespace or a namespace alias.
... It is clearly a bad practice. The solution is *not* to deploy it.
Wow! I thought we were being reasonable until this point. Apparently, I'm a horrible developer and clearly do bad things. In case my sarcasm isn't obvious, I do not accept your criticism of what I showed in the example. It *is not* bad practice.
Well, I obviously was not very successful arguing my point, was I? :-) Somehow cramming a view into a sentence or two brings the results exactly opposite to anticipated. My humble apologies (I never meant to imply anything "horrible") and please let me try again. I feel that our good vs. bad are relative. Namely, within the scope of your example it is clearly good. I interpret the example above as the programmer saying -- why formalities amongst friends, call me Rob. And that clearly works wonderfully as in your example with "Dad" as it does not lead to ambiguities. In that context I personally do not feel that in your example "from" is any less meaningful -- I have the "using" directive right in front of me and even without it I cannot resist but read "std::string s(from(i));" just as it is written -- "string s from i". I can't really think of anything else apart from what it *actually* does. Having said that, as calling "Dad" in a crowd is likely to turn a few heads, deploying using something-long something-short; typedef something-long something-short; within a bigger scope it is likely to lead to ambiguities and confusion. The bigger the scope the less meaningful is "from", i.e. doing so should (IMHO) be avoided. And that IMHO is not limited to this particular "from". *That* is what I referred as bad practice (I am guilty of interpreting your example too liberally). Again, please accept my humblest apologies for my clumsy attempt to explain my position. I am hoping I managed it better this time. V.

On Wednesday, February 18, 2009 12:44 AM Vladimir Batov wrote:
void f() { using boost::<something>::from; ... std::string s(from(i)); ... s = from(j); // etc. }
"from" is not as meaningful. That name almost requires retaining the enclosing namespace or a namespace alias.
... It is clearly a bad practice. The solution is *not* to deploy it.
Wow! I thought we were being reasonable until this point. Apparently, I'm a horrible developer and clearly do bad things. In case my sarcasm isn't obvious, I do not accept your criticism of what I showed in the example. It *is not* bad practice.
Well, I obviously was not very successful arguing my point, was I? :-) Somehow cramming a view into a sentence or two brings the results exactly opposite to anticipated. My humble apologies (I never meant to imply anything "horrible") and please let me try again.
I accept your apology. [snip]
The bigger the scope the less meaningful is "from", i.e. doing so should (IMHO) be avoided. And that IMHO is not limited to this particular "from". *That* is what I referred as bad practice (I am guilty of interpreting your example too liberally).
The problem is, as Scott (I think) noted, "from" is a preposition, not a verb. When combined with "string" as in string::from(i), it works well. Without that scope, it fails. _____ Rob Stewart robert.stewart@sig.com Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Stewart, Robert Sent: 13 February 2009 18:48 To: boost@lists.boost.org Subject: Re: [boost] Review Request: Introduction of boost::string namespace and string-conversion functions
Therefore, unless something major comes up later we are settling on "boost::string".
That's rather dismissive of the complaints. "text," "convert," and "conversion" seem at least as good as "string."
Would "lexical" as a namespace name help to remind of the link to lexical_cast? (The dictionary meaning is not quite right - but lexical has been hijacked already?) Paul --- Paul A. Bristow Prizet Farmhouse Kendal, UK LA8 8AB +44 1539 561830, mobile +44 7714330204 pbristow@hetp.u-net.com
participants (10)
-
Andrey Semashev
-
Hartmut Kaiser
-
Ilya Sokolov
-
Paul A. Bristow
-
Rutger ter Borg
-
Scott McMurray
-
Stewart, Robert
-
vicente.botet
-
Vladimir Batov
-
Vladimir.Batov@wrsa.com.au