Boost logo

Boost :

Subject: Re: [boost] [outcome] To variant, or not to variant?
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2017-05-31 17:06:51


Le 31/05/2017 à 15:15, Niall Douglas via Boost a écrit :
> On 31/05/2017 11:31, Vicente J. Botet Escriba via Boost wrote:
>> Does none_t mean success or failure?
>> For what I see it means failure as it is not the result of value().
>> In addition it default construct to none_t.
>>
>> The mental model for me is
>> variant<optional<T>, error_code, exception_ptr>> m_storage;
> Surely it is actually:
>
> variant<monostate, T, error_code, exception_ptr>
>
> std::monostate at the front of the typelist gives std::variant
> default-construct-to-empty semantics.
optional<T> also give you that :)
>
>>> Perhaps this could even be exposed even more so that user code could
>>> explicitly provide both a value and an error -- think "here's a value,
>>> but it was truncated" or "here's the 5 values you asked for, but
>>> there's more", both fairly common in system APIs. Or for things like
>>> ambiguous matches where you still return the most likely candidate.
>>> Or dictionary insertion (duplicate key, but here's the value that's
>>> already there). Or many more such examples. (Though obviously in this
>>> case value() couldn't call ensure(). But that should make some people
>>> happy.)
>>>
>> This corresponds to the status_value [1] model where you store the
>> reason why you don't have a value or why you have it and an
>> optional<value>. As described by L. Crowl in [2], there are use cases
>> for status_value, expected and exceptions.
> Personally speaking, I have not found Lawrence's status_value proposal
> sufficiently value-adding over returning a std::pair to be worth
> implementing. Also, the STL already uses std::pair throughout for status
> returns, it's the convention, though I will agree to use it is mildly
> clunky e.g. unordered_map::insert().first.
Things are changing in the standard. We want more explicit types.
status_value is a very good class that responds to real cases.
>
> Now, that said, if expected<T, E> and status_value<Status, Value> could
> be combined into a single object, that I can see significant value in.
Why and how do you want to combine them. One is a sum type the other a
product type.
These classes are useful on its own use cases.
> It's something I've often pondered for Outcome as well because it could,
> if done right, let me eliminate error_code_extended.
>
> The main thing which has stopped me is the potential confusion. For
> example, right now we have result<T> which can be
> empty|T|error_code_extended. If I instead made:
>
> template<class T, class Payload = void> class result;
>
> Now result could be (empty|T|std::error_code U Payload). But if this
> review to date with 600+ emails has been complicated, imagine a review
> of such a payload-carrying result object?
>
> std::error_code + payload is obvious. But, what does an empty state +
> payload mean? I have no idea.
>
> Indeed, what does a T state + payload mean? I guess that is Lawrence's
> status_value<> use case, but the problem is that the Payload type is
> fixed between variant states of empty|T|std::error_code and that surely
> is not particularly useful, you'd want different payload types with each
> of T or std::error_code. That's why I didn't implement it.
You lost me.
>
> Still, I'd be interested in what people think. The other option is
> empty|T|status_value<std::error_code, Payload>, that would make more
> sense, but at the potential cost of bloating the stack significantly
> which could surprise end users in a way error_code_extended can not.
>
You lost me definitely.

status_value is a product type because we need some additional
information even when the operation succeeds. The status is there to
convey this information, but conveys also the information explaining why
the result is not there.

status_value<S,T> could be seen as pair<variant<Sucsess, Failure>,
optional<T>>

There is an invariant Success <=> optional present and Failure <=>
optional not present.

You could as well see it as variant<pair<Sucsess, T>, Failure> or
expected<pair<Sucsess, T>, Failure>

Vicente


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