Re: [boost] [Review] UUID library (mini-)review starts today, November 23rd

Andy,
...
The first thing that comes to mind is size. A uuid class that holds the
data at text ... As a much more minor note, ...
I thought you might jump on my mikki-mouse string-based UUID... and in fact it was a trap of a sort. :-) I had a strong impression that the discussion in this thread revolved too much about actual implementation (MAC retrieval springs to mind) and too little about the interface. Yes, the implementation is important but it is the interface that makes it or breaks it as far as user's acceptance is concerned. That (acceptance) buys you time to improve the implementation hidden behind the interface. My concern with the proposal is that IMHO the interface has not been given enough consideration from the user perspectives.
I agree that many users do not care about the algorithm used. If they really don't care, is it an issue to use the boost::uuids::uuid_generator since they don't really care what it does anyway?
I feel that "do not care" is an oversimplification. The user does care -- he wants the "best available" without getting bogged down investigating what that "best available" exactly is. That is what Linux uuid_generate() gives the user right out of the box. To be successful boost::uuid just has to match that offer.
I believe they would just use this function and assume all is well.
I have to disagree. As a user I do not want to *assume*. I want to *know* that my application uses the available infrastructure to the fullest. That way if/when something goes wrong, it'll the OS to blame and not my application.
Those who care will look at what boost::uuids::uuid_generator does and decide for themselves.
Unfortunately, the reality begs for correction. I do care. However, with dead-lines approaching and the boss breathing down my neck I simply have no resources to look at every damn thing to decide for myself. In fact, I do not want to as I expect much-smarter-than-me people to have taken care of that for me. Exactly as I do not try reinventing std::map (even though I am aware of other than red-black-tree algorithms available).
They will likely be happy as long as there are the options that they want.
Giving options is merely part of the deal -- people often hate choice/options as they have to stop/think/evaluate/decide -- that process in time-consuming and draining, it distracts people from their main task. The only option pretty much guaranteed to succeed IMHO is the "best available" option.
I do want boost::uuid to provide algorithms to create uuids. I don't want platforms that don't provide an algorithm to not be able to easily create a uuid. Thus I don't want boost::uuid to be just a wrapper around OS functionality.
I do not think I said I wanted to see boost::uuid to be just a wrapper. In a nut-shell I'd like to see boost::uuid providing the user with the "best available" option. If that means Linux uuid_generate() or your own algorithm under the hood, then it's fine by me.
Does boost::uuid provide superior support and a upgrade path? ...
I would agree, that boost::uuid will never have the support of industrial/commercial scale. I now think that boost::uuid should provide a windows_uuid_generator (that uses UuidCreate), a linux_uuid_generator (that uses uuid_generate), plus possibility others platform specific ones, plus some of it's own. Then a boost::uuids::uuid_generator could use one of these if available and if not, use it's own generator. This would give users the support and upgrade paths that you are talking about.
Makes a lot of sense to me. Saying to the user -- Dear user, I've done the hard yards for you and I've come up with the best option available on your platform -- is a lot. I believe the overwhelming majority will be very happy. The curious ones (or with too much time :-) on their hands) will still be able to play with explicit uuid generators via "uuid id(some-generator);"
... I do believe that a null uuid is a valid uuid, but regardless, if the common use case really is as you say, then sure lets have the default constructor call a function to generate a unique uuid. And still provide a way to create a null uuid.
Please do not take my word for it. Just look around at your own usage pattern of the default constructor beyond the UUID domain.
My work also heavily relies on uuids, but we almost never create one ourselves in code. We get almost all our uuids from the database that our program uses.
Understood. Our usage is pretty much the same. Still, if my component does not create UUIDs, then IMHO it has to state that with Foo() : uuid_(boost::uuid::null()) // initially invalid {} That way the other poor soul coming after me won't be getting any wrong ideas/interpretations what the code is actually doing.
I would be surprised if there aren't many others that use uuids in the same way, they receive them, they don't generate them.
Understood. I do not believe you should be providing the default constructor for that usage pattern -- it feels like the copy constructor is in order here. All in all my impression of the *current* situation with the proposal is that at *present* we have many useful and promising bits and pieces lying around. I see good ideas. I see good suggestions. I fail to see the product. It surely is a good start but to me we have not reached the destination yet. I'd be more comfortable after I see those bits and pieces taking shape. For me that shape primarily would be the interface and the documentation -- the initial pieces of the contract between the user and the implementor. Once both parties are happy with the contract, you'll beaver away providing the content/implementation. Thanks, Vladimir.

On Tue, 2 Dec 2008 11:21:08 +1000, Vladimir.Batov@wrsa.com.au said:
Andy,
...
The first thing that comes to mind is size. A uuid class that holds the data at text ... As a much more minor note, ...
I thought you might jump on my mikki-mouse string-based UUID... and in fact it was a trap of a sort. :-) I had a strong impression that the discussion in this thread revolved too much about actual implementation (MAC retrieval springs to mind) and too little about the interface. Yes, the implementation is important but it is the interface that makes it or breaks it as far as user's acceptance is concerned. That (acceptance) buys you time to improve the implementation hidden behind the interface. My concern with the proposal is that IMHO the interface has not been given enough consideration from the user perspectives.
Agreed, the interface is very important.
I agree that many users do not care about the algorithm used. If they really don't care, is it an issue to use the boost::uuids::uuid_generator since they don't really care what it does anyway?
I feel that "do not care" is an oversimplification. The user does care -- he wants the "best available" without getting bogged down investigating what that "best available" exactly is. That is what Linux uuid_generate() gives the user right out of the box. To be successful boost::uuid just has to match that offer.
Your right. Its not that they don't care. Its that they don't want to have to care. They want to _know_ that the algorithm is great and move on.
I believe they would just use this function and assume all is well.
I have to disagree. As a user I do not want to *assume*. I want to *know* that my application uses the available infrastructure to the fullest. That way if/when something goes wrong, it'll the OS to blame and not my application.
Those who care will look at what boost::uuids::uuid_generator does and decide for themselves.
Unfortunately, the reality begs for correction. I do care. However, with dead-lines approaching and the boss breathing down my neck I simply have no resources to look at every damn thing to decide for myself. In fact, I do not want to as I expect much-smarter-than-me people to have taken care of that for me. Exactly as I do not try reinventing std::map (even though I am aware of other than red-black- tree algorithms available).
They will likely be happy as long as there are the options that they want.
Giving options is merely part of the deal -- people often hate choice/options as they have to stop/think/evaluate/decide -- that process in time-consuming and draining, it distracts people from their main task. The only option pretty much guaranteed to succeed IMHO is the "best available" option.
I do want boost::uuid to provide algorithms to create uuids. I don't want platforms that don't provide an algorithm to not be able to easily create a uuid. Thus I don't want boost::uuid to be just a wrapper around OS functionality.
I do not think I said I wanted to see boost::uuid to be just a wrapper. In a nut-shell I'd like to see boost::uuid providing the user with the "best available" option. If that means Linux uuid_generate() or your own algorithm under the hood, then it's fine by me.
I wasn't trying to say that you did or didn't want boost::uuid to just be a wrapper. I was simply stating that I didn't want boost::uuid to just be a wrapper. Sorry I was unclear.
Does boost::uuid provide superior support and a upgrade path? ...
I would agree, that boost::uuid will never have the support of industrial/commercial scale. I now think that boost::uuid should provide a windows_uuid_generator (that uses UuidCreate), a linux_uuid_generator (that uses uuid_generate), plus possibility others platform specific ones, plus some of it's own. Then a boost::uuids::uuid_generator could use one of these if available and if not, use it's own generator. This would give users the support and upgrade paths that you are talking about.
Makes a lot of sense to me. Saying to the user -- Dear user, I've done the hard yards for you and I've come up with the best option available on your platform -- is a lot. I believe the overwhelming majority will be very happy. The curious ones (or with too much time :-) on their hands) will still be able to play with explicit uuid generators via "uuid id(some-generator);"
... I do believe that a null uuid is a valid uuid, but regardless, if the common use case really is as you say, then sure lets have the default constructor call a function to generate a unique uuid. And still provide a way to create a null uuid.
Please do not take my word for it. Just look around at your own usage pattern of the default constructor beyond the UUID domain.
Hmm, I looked at some other value types in boost and this is what I found. boost::gregorian::date() creates an 'not_a_date_time'. One can exclude this constructor with a #define. boost::posix_time::ptime() is the same as above boost::function() is initialized as empty std::string() is initialized as empty boost::numeric::interval() the created interval is the singleton zero boost::quaternion() initialized each component/member to the default values for their type (i.e. zero for floating numbers) boost::optional() is uninitialized boost::rational() is 'zero' And so I think we are debating the questions: Is a null uuid a valid uuid? And, what should the default constructor do? Create a null uuid or a unique one? Maybe there shouldn't be a default constructor, and force one to be explicit when they make a null uuid and when they make a unique uuid as: boost::uuids::uuid u1(boost::uuids::null()); boost::uuids::uuid u2(boost::uuids::uuid_generator());
My work also heavily relies on uuids, but we almost never create one ourselves in code. We get almost all our uuids from the database that our program uses.
Understood. Our usage is pretty much the same. Still, if my component does not create UUIDs, then IMHO it has to state that with
Foo() : uuid_(boost::uuid::null()) // initially invalid {}
That way the other poor soul coming after me won't be getting any wrong ideas/interpretations what the code is actually doing.
This is what I want to prevent as well. I'm concerned about the user who does: boost::uuid u; // this create a unique uuid and does not realize that they just ran a computational intensive function when they didn't need or want to.
I would be surprised if there aren't many others that use uuids in the same way, they receive them, they don't generate them.
Understood. I do not believe you should be providing the default constructor for that usage pattern -- it feels like the copy constructor is in order here.
Fair. These people are likely either doing: boost::uuid u = get_uuid_from_somewhere(); // eg from database or boost::uuid u; get_uuid_from_somewhere(u); // eg from database The second case would create a unique uuid unless they remembered to do: boost::uuid u(boost::uuid::null()); It sounds very easy for one to forget. This doesn't change symentics, it is just less efficient. Regardless of what the default construction does (null, or unique uuid), I do really like having an explicit way of creating a null uuid. Something like: boost::uuid u(boost::uuid::null()); In fact boost::uuid::null() should be just another uuid generator.
All in all my impression of the *current* situation with the proposal is that at *present* we have many useful and promising bits and pieces lying around. I see good ideas. I see good suggestions. I fail to see the product. It surely is a good start but to me we have not reached the destination yet. I'd be more comfortable after I see those bits and pieces taking shape. For me that shape primarily would be the interface and the documentation -- the initial pieces of the contract between the user and the implementor. Once both parties are happy with the contract, you'll beaver away providing the content/implementation.
Thanks, Vladimir.
Regards, Andy Tompkins
participants (2)
-
Andy Tompkins
-
Vladimir.Batov@wrsa.com.au