On 02/16/2014 08:35 AM, Andrzej Krzemienski wrote:
I have a suggestion regarding the documentation. It is abut the first page. I am expressing my preference, but I am pretty sure I am not the only person here with this expectation. I am a very impatient man and I expect of the first page a number of answers quickly, or otherwise I will be not interested. When I see "Conversion" in the name of the library, I will need the following questions answered quickly (I guess I am not more arrogant than an average stressed programmer):
1. Is it only string to T and T to string conversions, or arbitrary T to U conversion? 2. Will it consider locale? 3. Will it return optional<T> (or some such) so that I can decide myself how to deal with conversion failure? 4. How will I use it. Give me a minimum example.
In other words, I need to see from the first page what this library will and will not give me.
I would also suggest not to start with the comparison with lexical_cast. Your users may not even know lexical_cast. Also, there is something discouraging when I read how your library differs from some other library rather than learning what your library is. I see your point. Unfortunately, I feel somewhat paranoid as lexical_cast comparisons dogged my V1 proposal all the way through. Back
I've extended the Introduction section to address your #1&2 comments. As for #3&4 I suspect I am lacking the ability to express myself succinctly enough to squeeze those into the Introduction... without turning it into "War and Peace"... which would work against me with the impatient kind. ;-) then people's reactions were quite natural -- we already have a conversion API which seems to be a potentially suitable foundation; why not use it? They were at the beginning of the "road" I already went but I had to answer the same (not always kind and polite) questions about lexical_cast over and over again. And youngsters are usually "quick shooters" -- quick and easy with grandiose statements and opinions, slow and reluctant with their own research beforehand. So, now I put in (indeed) a lot of stuff related to lexical_cast -- design, performance, functionality comparisons... just in case... in fact, if we get to the review/discussion stage, I am sure people will be asking -- why not lexical_cast, why does not it behave like lexical_cast?
Two other suggestions for the initial page. 1. Mention that it works with non-DefaultConstructibel types. It is unusual (in the positive sense) for a conversion library. 2. Since you mentioned that convert can be used without specifying the second (streamer) argument, show this in the initial example: let it be really simple. I hope I've addressed your #1 in the Introduction section. Please see if you find it satisfactory. As for #2 I have to admit I reconsidered my original position. Indeed, I had the converter parameter in convert<T>::from(value_in, converter) defaulted to sstream_converter in my own code. Because I was lazy and did not care for its performance (I have other chunks "eating" so much more).
Now, as I put it up for everyone to see, it's a different story. My original lazy approach had two drawbacks -- convert/api.hpp had sstream_converter.hpp included (an unnecessary coupling) and convert<T>::from was creating a converter every time it was called. As I described in the Performance section it has quite a detrimental effect on performance. As I said, *I* am not concerned (for my current applications)... but I do not want to give that loophole to people to explore, discover that performance sucks in their settings and come back swinging... just the same why I took the implicit converter to T from convert<T>::result as soon as you mentioned it -- I *personally* find it very convenient (no need for "value") but defending it is a loosing battle IMO.
And one other thought (it is not really a suggestion for Boost.Convert, but a general observation regarding string conversions). Your library is mainly about converting string to T. T to string will be less common. Hmm, here with all due respect I really have to disagree on various levels. :-)
In my neck of the woods, string-to-T and T-to-string are represented quite equally. Say, we consider the management of configuration files. Reading values (string-to-T) from cfg files is (to me, anyway) on the same scale as writing updated values back (T-to-string). Same goes for a component in a processing pipe or a node in a network -- reading/converting a lot of XML, converting/writing a lot of XML.
And I find it hard to imagine that someone would use it as T to U conversions. Again, I am far from sure about that. I do currently have to have OS-native MBCS (MSWin and Solaris) to UCS-2 and UCS-4 string conversions. They are a separate lib. Can't immediately see anything wrong in incorporating it into the 'convert' framework. Then I remember Vicente having a 'conversion' proposal to address that T-to-U conversion in a generic way. So, he must have had a need for it also. I am not saying you are wrong. I just do not know. Consider the templates example. Stroustrup purposefully designed them in a generic way. Their deployment exploded often in surprising ways. I am certainly no Stroustrup but you get the idea. When converting from T to string, you do not really need to return optional<T>, because it is not possible that this conversion can fail. Any T always has a string representation, doesn't it? I wonder (but I do not have a good answer) if conversion in this direction should have the same interface. Uhm, I would not be that quick saying that T-to-string conversion can never fail. It depends on complexity of the conversion and the used character set, etc. What if T is a complex class which in its conversion depends on other classes to behave and they don't? What if the conversion depends on, say, formatting specification and it is not met or is invalid?
On top of it, uniformity (and, therefore, predictability) of API and behavior is quite important IMO. Special (and questionable I might say) handling of one special case IMO is not worth it (again IMO). V.