
2014-02-16 23:13 GMT+01:00 Vladimir Batov
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'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. ;-)
Now, I can definitely find all my answers in the Introduction. What I would like to suggest as an option (but please do not treat this as a requirement or an expression of dissatisfaction -- I can keep giving suggestions forever, sometimes in a cycle) is to put a very very short code snippet that will show me how I will be using the library.
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 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?
Comparison with lexical_cast, and (even more importantly) answering the questions "why would I use Boost.Convert library instead of lexical_cast" and "why did you not extend lexical_cast instead" and "why would I need lexical_cast anymore" are very important for your library's documentation -- I agree. It is just that I am not sure these explanations belong to the Introduction page. But I leave it open. I am satisfied with the improved introduction as it is (except for the one tiny suggestion below).
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.
Ok, I get it: you do not want to suggest an inefficient use.
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.
So, you say, it could be used to convert between two different string encodings? I didn't think of it but it looks really useful. So useful that it deserves a bullet in the Introduction. Can it be used to convert from string to wstring? For some background, Vicente's library IIRC tried to emulate to some extent the non-member conversion operator. It was supposed to convert between two types that were meant to represent the same abstraction but written by two different programmers/libraries: time_t t1; ptime t2; MyLib::Time t3; they all represent the same thing and the library should offer a universal way to convert between them.
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?
This is an interesting point. If a conversion fails because it required to acquire some resources and it failed to get them, or because the object was in a disallowed state (some assertion-like thing failed), do you want to return an empty result, or just throw?
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).
Agreed. Regards, &rzej