From: Dave Gomboc (dave_at_[hidden])
Date: 2002-12-15 04:55:14
> > Conversion from T' to T is straightforward except when the value of
> > type T' is nil. In this case, the developer may want to throw,
> > default-construct the value of T, or assert. Template policy choice?
> > (Perhaps that's overkill.)
> As Peter said, default-construct T undermines the whole purpose of
> optional. The best is, IMO, to leave it undefined in that case.
Myself, I'd prefer
x = y;
to throw when the assignment happens. However, sometimes people don't
want that (e.g. those compiling with BOOST_NO_EXCEPTIONS). In a debug
compile, an assert is possible, but what to do in a release compile? I
suppose aborting is possible, but highly unfriendly. Instead, either your
suggestion of leaving the value alone (which means it would be
uninitialized if it hadn't been previously set) or setting it to the
default value make sense to me. I thought that the latter would give more
consistent behaviour so that it would be easier to debug, but I'm not
wedded to the idea. I do agree that these other options are undesirable
to the extent that they work against the purpose of optional<>.
That aside, the big issue remains whether people consider the "nil" value
to be truly exceptional, versus it being just another possible value. I
think that your view is the former, and that this is reflected in your
interface design. It really does highlight attention on the fact that
there's this "extra" possibility, and that one shouldn't forget to deal
with it. It's screaming, "Hey! Don't forget about the nil value!", and I
can understand why you view this as very positive.
It's just as visible from my comments that my view is the latter. If you
treat nil as just another acceptable value, instead of the absence of one,
then the algebra works completely, and also quite usefully (e.g.
consider relational algebra). So why wouldn't I want to do just that?
"nil" doesn't have to mean 'invalid', or 'uninitialized', or 'danger,
danger' ;-) in any particular circumstance -- of course it _can_ mean
those things, depending on what you're using it for. But it might simply
mean there was nothing to return, nothing to pass, nothing to inspect,
nothing to whatever. The asymmetry between the "nil" value and the other
values in the proposed interface really bothers me _because_ to me "nil"
is just "nil", and it's only of specific interest in the same manner that
zero might be of specific interest in some other circumstance. Sometimes
you want to test for zero, so it's handy to have a shortcut for it, but
much of the time it's just an integer.
I would guess (handwaving alert ;-) that the traditional mechanism for
indicating an "optional" value uses a pointer because that was more
convenient than passing a separate flag alongside the value. Let's not
forget that this practice predates data structures, never mind
object-orientation -- a pointer is a legacy interface for this job. Now
that the extra bool can be wrapped and hidden away, there's no longer a
need for pointer-like treatment. And I'd argue (granted, perhaps
unsuccessfully <grin/>) that the interface is counter-productive, because
people won't ever really become comfortable working with "nil-ness" as
long as the interface promotes it as being a special case.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk