Boost logo

Boost :

From: Joel de Guzman (djowel_at_[hidden])
Date: 2002-12-14 18:28:57


----- Original Message -----
From: "Fernando Cacciola" <fcacciola_at_[hidden]>

> I think it can be done in a way as to not make it confusing.
> For instance, iterators also have operator*() and ->(), yet they are not
> pointers.

Aren't they? In the conceptual level?

> Certainly, they are _a lot_ more like pointers than optional<> because they
> have pointer semantics in terms of shallow-copy and aliasing, but,
> for instance, you cannot delete an iterator, but I don't think that

Is a pointer required to point to heap allocated data? What about
int a = 3; int* ap = a; ? Isn't that a pointer? I can't delete ap.

> the pointer-analogy had drawn peoplo into that sort of mistakes.
> For optional<>, the key to sucess resides in the way you present it,
> and in the way the pointer-like interface is used.
> >
> > For what its worth, I prefer the union concept. Union semantics clearly
> > state that
> > you can have either or (i.e., not both).
> Yes.

> But I think that a container is even better, because containers inherently
> models the fact that you can have a value or not.

I can easily give you a container that fails your definition:
Isn't char a[3]; a container? Yet, it does not "model(s) the fact that
you can have a value or not". What about tuples, are you saying
that that is not a container?

> This is closer in meaning to optional than a union.

Think again. Isn't variant a *container* that holds only one value
at a time? That supersets the definition of the optional AFAICT.

> It is an error to try to access one element of an empty container
> just as it is an error to try to access a non-existent value.

It is also an error for a variant to access T from variant<T, nil_t>
if nil_t is in effect and T is therfore a "non-existent value".

> The union mapping is good, but the container mapping is better becuase
> the undefined behaviour of invalid access is directly supported by the
> container concept, while the union concept requires the additional
> element of a type with semantics unfamiliar to C++.

What semantics are you referring to? The semantics of
variant<T, nil_t>? optional<T>? maybe<T> ? All of these
are new grounds (and thus unfamiliar) to the C++ programmer.

What's wrong with borrowing a well formed concept from
other languages? That's definitely better that concocting a
half-cooked version of what's already a mature concept in
other languages.

> With a union-like interface, this is not so because the union has always
> a well defined state, so if you try to accesss an uninitialized optional,
> this model gives you nil_t.

Wrong! Accessing T in variant<T, nil_t> does not give you nil_t.

> nil_t by itself is not undefined, so to make sense of the concept of
> optional value, which itself implies that the value might not exist,
> either the programmer or the interface-under-the-hood must make sure
> that the result nil_t is treated as a postcondition violation.
> If you trust my experience with this tool, I assure you that if you are
> accesing the value of a conceptually non-existent object,
> you've made a mistake on the code because the execution path
> should never had reached that point.
> This is why I prefer the container model: You cannot extract one
> element of an empty container. If you try, you get undefined behaviour.
> However, the syntax of a container interface does not help you
> to make sure you have checked for non-emptyness. Of course,
> this happens all the time with any container and it has alawys
> been the programmers responsability to make sure of the object
> you try to access is actually there.

All these are based on a wrong premise. I highly suggest that
you look into discriminated unions (aka variant) more closely.

Regards,
Joel de Guzman
joel_at_[hidden]
http://www.boost-consulting.com


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