Boost logo

Boost :

From: Joel de Guzman (djowel_at_[hidden])
Date: 2003-08-30 20:58:45


Fernando Cacciola <fcacciola_at_[hidden]> wrote:
> Hi Mat,
>
> Thanks for the input.
>
> optional<> is now out on the field and it is the only utility of its kind
> I've ever seen in C++, at least in real use. This has the drawback that there
> is very little experience with it. Therefore, in a way it is a sort of

There's a lot of experience with it in other languages. Why not leverage that?
Haskell::Maybe for instance.

> experiment, even though it is now a fixed part of Boost.
> optional<> will evolve, that's for sure, as user's experience show which
> design desicions were right and which were wrong.
> I might even deprecate it and submit a replacement if it becomes clear that a
> drastic change is neccesary.
>
> Right now I still believe that the pointer-like interface is correct, because
> I add it specifically to solve a real problem and it did solve it.
> My first optional (named differently then) had the problem that it was really
> difficult to track which variables were 'optionals' and hence it was easy to
> forget to make the neccesary steps to mantain integrity (not to use an
> uninitialized optional). At some point I realized that I needed something at
> the syntax level that help me keep in mind that those variables are possibly
> uninitialized, and so I moved from value() member functions to operatos * and
> ->

If that's the only rationale for having the pointer-like interface, then pardon
me but, I find that very flimsy. There should be other means to attack the
problem (if it is a problem) without sacrificing the beauty of the interface.

> The pointer-like interface is just about syntax really.
> Instead of opt.value() you type (*opt) or opt->
> This alone shouldn't be a problem.

Right.

> What I think it is a problem are other design descicions that I made in order
> to make other parts of the interface with the pointer-like interface. Namely,
> the lack of implicit construction and direct assignment.

Sacrificing this in order to "track which variables were 'optionals'" ?, IMO,
is not a good idea.

> These two points are raised here by Mat and have been raised by many others
> in the past.
>
> My main argument is that if those were allowed, you could write:
>
> optional<int> opt ;
> opt = 1 ;
> int i = *opt ;
>
> and the assymetry didn't look right to me.

If optional had value semantics, it would be a lot cleaner:

    optional<int> opt;
    opt = 1;
    i = opt;

For those concerned about "track"ability, they can use an easy to
grep alternative:

    optional<int> opt;
    opt .reset(1);
    i = opt.get();

> Now I understand that generic uses of optional<> beg for conventional
> 'syntax' for assignment and initialization.

True!

> I could drop the pointer-like interface but only if replaced by some member
> function that aids to the fact that the value being accessed may be
> undefined, that is, I know from previous experience that the following code
> better be invalid:

That's a very reasonable solution.

[snip]

> Today, on the face of all the versions I've tried and the user report I have
> now about the uses you want but are unsupported, I will carefully think about
> adding direct initialization and implict construction yet retaining the

To be honest, I'm not really so sure about implict construction.

> pointer like interface which is intended to be a familiar 'syntax' for
> _accessing_ the optional in those contexts were uninitialized optionals have
> undefined behavior.

Is the pointer like interface really worth keeping? That's the point Mat was
trying to make, right? IMO, I can't see a reasonably balanced rationale, yet.
The pointer like interface sacrifices a lot for a small gain: to make it easy
to detect automatically. For those who are concerned that this is indeed a
problem, why son't they just use: opt.get(). Surely, that's very easy to track.

> That is, optional would have the straight interface of a value wrapper, with
> conventional value semantics and syntax, in all parts of the interface were
> behaviour is well defined even in presence of uninitialized optionals. This
> includes direct assignment and implicit construction.
> But for accessing the value, which is the only operation that has undefined
> behaviour if it is uninitialized, you need to do it through operators * and ->
>
> Well, this is a good time for all of you to speak. The heat is on again.

I'm in favor of dropping the pointer like interface. IMO, It sacrifices a lot for
a small gain. It causes more confusion especially when having to support
more value semantics. IMHO, mixing pointer and value semantics is plain
and simply a kludge.

-- 
Joel de Guzman
http://www.boost-consulting.com
http://spirit.sf.net

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk