|
Boost : |
Subject: Re: [boost] [Review] UUID library (mini-)review starts today, November 23rd
From: Vladimir Batov (batov_at_[hidden])
Date: 2008-11-28 08:14:47
Andy,
Thank you for taking the criticism the right way and my apologies if some of
my comments sound(ed) somewhat harsh. It is never my intention. I won't be
addressing the points below directly as some issues I raised are petty (and
I somewhat wish I did not raise them). I admit I felt uneasy with the
proposal but could not pin-point what it was. I'll try again.
Background: We are in our project currently using uuid facility heavily and
very dependent on it. The version we use (from memory) is something like
(it's not necessarily exactly what we use and I'll omit some scaffolding and
stick with the basics):
struct uuid : public std::string
{
typedef std::string base;
uuid() : base(generate()) {}
explicit uuid(string const& s) : base(s) {}
static uuid null() { return uuid(std::string()); }
private: std::string generate();
};
On Linux the generate() function calls uuid_generate(). No one (in our
project anyway) can be bothered choosing between uuid_generate_random() or
uuid_generate_time() -- uuid_generate() takes care of the guess work and
picks the best available. The same on Windows -- it'll probably be
UuidCreate()&UuidToString(). Given that uuid above is merely a wrapper over
OS facilities, we get known behavior, we are guaranteed "support" and an
automatic "upgrade" if/when the standard changes or a new better algorithm
becomes available.
For me (a collective nebulous "me") to switch to your boost::uuid it has to
provide something to win me over. Let's see what that might be.
Does boost::uuid provide superior implementation? Maybe. If it is, that was
not spelt out sufficiently visibly for me to pick up in the documentation.
Therefore, as it is now the answer regretfully has to be 'no'.
Does boost::uuid provide superior interface? That issue might get very
subjective and personal. Therefore, I'll re-focus on if boost::uuid is
user-friendlier. Maybe but I doubt it as an ordinary user does not want to
be bothered choosing between algorithms. If uuid_generate() and UuidCreate()
can make that choice for me, it is good enough for the overwhelming majority
of uuid applications. Therefore, the answer seems again 'no'.
Does boost::uuid provide superior support and a upgrade path? With all due
respect I have to say 'no' again as your support (no matter how enthusiastic
it is) cannot compete (on industrial/commercial scale) with vendor-backed
support. uuid_generate(), UuidCreate() as printf() come with the system. One
has to have really serious reasons to use something else instead.
Does boost::uuid provide superior documentation? Well, my impression is that
it is 'no' again.
What boost::uuid does immediately entice an ordinary user with then it is
Boost reputation. However, in all honesty it's not boost::uuid property per
se but the reputation for quality of the Boost libraries built over those
many years. In this thread I hear some people say "it's OK to ship". I
disagree. Every new library has Boost reputation to uphold. It takes time to
build such a reputation. It does not take long to lose it -- a couple of
just "OK to ship" libraries will probably do.
I'd probably be more comfortable if boost::uuid took the approach of
boost::thread of providing consistent interface across many platforms via
re-use of the functionality provided by the OS (when available) rather than
duplicating it. Then though I'd expect the interface to be given
considerably more thought.
As for the interface I'll express my view to one of your comments below.
> I would not want the default constructor to generate a uuid. I don't
> want users to pay for that if they don't want it. Some use cases will
> not require generating uuids, only using them.
I have to disagree. I believe that the overwhelming majority of cases falls
into the following category -- "I introduce something when/because I need
that something". That is, by
Foo foo;
std::string str1;
std::string str2(params);
uuid id1;
uuid id2(param);
I create valid instances. Say, 'str1' is empty but it is still a valid
string. I create 'id1' because I need an uuid. You on the other hand use
uuid id2(param); // valid instance
uuid id1; // invalid instance
where #1 creates a valid instance but #2 creates an invalid instance (it
lacks its identifying property -- it's NOT unique). Therefore, you use the
same (visually and behaviorally) creation mechanism to achieve *different*
results. From the user perspective it is inconsistent and likely unexpected.
The case you are catering for with uuid() is not mainstream but quite the
opposite -- the user introduces something that he does *not* want. Such case
should be handled explicitly with the user actually spelling out what he
means like
Foo::Foo()
:
uuid_(boost::uuid::null()) // initially invalid
{}
Best,
Vladimir.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk