Boost logo

Boost :

Subject: Re: [boost] [outcome] On the design and documentation
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2017-05-27 06:38:13


Le 26/05/2017 à 23:23, Andrzej Krzemienski via Boost a écrit :
> 2017-05-26 9:03 GMT+02:00 Vicente J. Botet Escriba via Boost <
> boost_at_[hidden]>:
>
>> Le 26/05/2017 à 08:22, Thomas Heller a écrit :
>>
>>> On 05/25/2017 07:28 AM, Vicente J. Botet Escriba wrote:
>>>
>>>> Le 24/05/2017 à 21:44, Thomas Heller via Boost a écrit :
>>>>
>>>
>>>>> First of all, I don't agree with the strong (conceptual) relationship
>>>>> between
>>>>> optional (be it boost:: or std::experimental) in such a way that
>>>>> expected is a
>>>>> generalization of it. From what I understand, the purpose of
>>>>> expected/outcome/
>>>>> result is to be used as a mechanism to return the result of a
>>>>> function. As
>>>>> such it should also expose the semantics of it. Fortunately, we
>>>>> already have a
>>>>> (asynchronous) return object standardized (std::future). And this is
>>>>> my basic
>>>>> disagreement here: Why not model expected in the lines of future? With
>>>>> the
>>>>> main points being:
>>>>> - expected being movable only
>>>>> - expected<T,E>::value() should always return by value and
>>>>> invalidate this.
>>>>> - (I would really prefer the color .get though ;))
>>>>> So the question to Vicente/Niall is: what is the motivation to make it
>>>>> "optional-ish"? Do we have use cases which make this design undesirable?
>>>>>
>>>> expected is a generalization of optional as it is synchronous and could
>>>> return more information about why the the value is not there.
>>>>
>>> Right, I can see this argument now, let me try to rephrase it a little
>>> bit (correct me if I got something wrong please):
>>> We want to be able to have a mechanism to return (or store) a value which
>>> might not be there, and we need to know why it is not there. The class
>>> that's currently available which almost does what we want is optional, in
>>> fact, it is already used in such situations, so what we miss is the
>>> possible error. So here we are, and then we naturally end up with something
>>> like variant<T, E>. Makes perfect sense.
>>>
>>> My line of thought was mostly influenced by the property of being solely
>>> used as a return object. And well, we already have the asynchronous return
>>> objects, so why not go with something a synchronous return object which
>>> represents a similar interface/semantics.
>>>
>>> With that being said, I am still not sure if the result of both ways to
>>> look at it should converged into the same result.
>>>
>>> expected could be seen as the ready storage of a future.
>>>> future::get block until the future is ready and then returns by
>>>> reference :)
>>>>
>>> Except not quite ;)
>>> excepted indeed sounds like the perfect fit for the value store in the
>>> share state. The only problem here, is that it really requires some kind of
>>> empty (or uninitialized) since the value is only computed some time in the
>>> future (this is motivation #1 for the proposed default constructed
>>> semantics), having either a default constructed T or E doesn't make sense
>>> in that scenario.
>>> So it is more like a variant<monostate, T, E>.
>>>
>> From a high level I will see it as optional<expected<T,exception_pr>>. We
>> optional because we have in addition the not-yet-ready state. Once the
>> future becomes ready we have expected<T,exception_ptr>.
>>
> `optional<expected<T,exception_pr>>` is still not enough for the
> `future<T>`, because in `future` `T` is allowed to be an lvalue reference.
> :)
>
Right :) It cannot be neither std::variant<monostate, T, E>.

You are right: what expected<T&> could be needs to be defined. Not for
this precise future::then case, but for the use cases expected is
intended for.

Best,
Vicente


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