Boost logo

Boost :

Subject: Re: [boost] [variant] Maintainer
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2015-06-29 02:58:44


Le 28/06/15 16:29, Agustín K-ballo Bergé a écrit :
> On 6/28/2015 5:38 AM, Vicente J. Botet Escriba wrote:
>> Le 27/06/15 21:32, Agustín K-ballo Bergé a écrit :
>>> On 6/27/2015 12:38 PM, Vicente J. Botet Escriba wrote:
>>>> I would accept Eggs.Variant without even a review (or with a minimal
>>>> review) as an experimental library as part of Boost.Variant after some
>>>> minimal adaptation to fit in Boost of course.
>>> First of, as I have already said before, Eggs.Variant is an
>>> experiment. As such it is highly unstable, and I reserve the right to
>>> change things in any way I see fit, with no regards for backwards
>>> compatibility, maintenance, or support. I have made these kinds of
>>> changes in the past, and I have more planned for the near future. I
>>> think it would be unwise to make it a part of Boost, even as an
>>> experimental library, until the design has fully hatched ("Eggs", get
>>> it?).
>> Agustin, this is exactly the kind of constraints of an experimental
>> library. When the design is fully hatched then it moves to non
>> experimental.
>
> I fail to see the point in including an experimental library that
> changes its interface every month into Boost, which is released every
> 3 months or so. By the time you get your hands in a release, the
> interface of the library has already changed. And the library as such
> would only exist for a single release.
>
> Who would benefit from Boost packaging old snapshots of experimental
> libraries?
>
> Perhaps you'd wish to bring back the Sandbox
> (http://www.boost.org/community/sandbox.html), which has been
> superseded by standalone repositories since the move to Git.
Yes, Boost.Experimental could be something like the old sandbox, but
instead of having a sandbox that is not fixed, it will be fixed 3 times
a year. This gives some stability to users that want to play with.
>
>>> For instance, the visible empty state is not going anywhere. As a
>>> fundamental building block, I cannot afford to pay the cost of double
>>> buffering, heap allocation, restrictions to nothrow-move-constructible
>>> alternative types, etc.
>> There is something that I don't like of the possibly empty variant. It
>> confounds the empty state and a hidden error state. When we assign a
>> type A to variant containing a type B the resulting variant can be
>> empty (contains a different type C).
>
> Eggs.Variants doesn't have an error state, only an empty state as
> `union`s do. Switching the active member of a `union` is a two step
> operation:
>
> - First the active member (if any) is destroyed, leaving the `union`
> in an empty state (no active member).
>
> - Then, a new member is activated via in-place construction. If
> construction fails with an exception, the `union` remains empty.
This is what we are calling the error state :). So Eggs is confounding
the empty and the error state (even if this is not stated explicitly)
>
>>> The abstractions I built on top of it might, since they are the ones
>>> who attach meaning to the variant, but it is up to them to make those
>>> choices. Likewise, I'm not considering implementing support for void
>>> and reference types as alternatives.
>> Could you tell us more about the rationale? it is because some wrappers
>> as void_t and reference_wrapper<T> can be used instead?
>
> It is because `union`s don't take those as members.
>
> I did briefly experimented with implicit conversion to wrappers, as
> those you mention, but it interacted in funny ways with interfaces
> where a "scalar" value appears (construction, assignment, relational
> ops). I concluded that forcing the higher level abstraction to do the
> wrapping and be aware of it would be less surprising.
Thanks for clarifying.
>
>> BTW, how eggs::variant<T,T> behaves?
>
> Just as a `union U { T a; T b; };` would. It has two distinct members,
> and you can only access the active one.
>
> Eggs.Variants additionally provides access to the underlying storage,
> both raw and typed, via its `target` member function. Based on recent
> discussion on the reflectors, I will be modifying `target<T>()` to be
> able to access it when either of the two members are active, since
> it's logically equivalent to a cast on the underlying storage address
> and I understand it to be well-defined under strict aliasing rules
> (see http://melpon.org/wandbox/permlink/Zw59kxEmvp7M82M5).
>
While I see added value to variant <T,T> I would make any access with
the type T ill-formed, as you do already for get, and provide access
only throw the index. `union U { T a; T b; };` works because we have
using tags `a` and `b`, but i doest provides access by type.

> There are several other places in which I have yet to consider whether
> SFINAE or hard error is appropriate.
>
> As far as I know, I only depart from what a `union` would do for
> initialization. Due to the discriminator, I cannot provide both
> default-initialization and value-initialization as `union`s do, so I
> only provide the cheap one.
>
Why you can not default initialize to index 0?

Vicente


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