Boost logo

Boost :

Subject: Re: [boost] [outcome] Possible extensions/changes to std::experimental::expected
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-26 12:02:10


2017-05-26 3:00 GMT+02:00 Gavin Lambert via Boost <boost_at_[hidden]>:

> On 25/05/2017 19:44, Vicente J. Botet Escriba wrote:
>
>> 3. uninitialized default constructed expected<T,E>
>>
>
> I've already stated my opinion on this elsewhere.
>
> Outcome doesn't implement comparisons between Outcomes. He pretend that we
>> don't need them. In addition the mix of comparisons and implicit conversion
>> give us some surprising cases as described in Andrzej blog.
>>
>
> I agree with Niall -- putting one directly in an ordered collection is
> bizarre and if someone really wants to do that then it should be left up to
> them to define what ordering makes sense to them. operator< should
> absolutely not be implemented and I would hesitate before providing any
> free standard ordering methods.
>
> The implicit conversion from T to expected<T,E> is a consequence of
>> wanting that expected<T,E> should behave like a T. But this is not right. A
>> expected<T,E> is not a T.
>>
>
> Implicit construction does not imply is-a, it implies is-superset-of.
> Which is true, expected<T,E> is a superset of T.

Maybe this is just subject to one's private opinion, but I do not agree
that expected<T, E> is a superset of T, in the same way as optional<T> is
not a superset of T or a vector<T> is a superser of T. They only can
*store* a T inside but they are not T or a superset thereof: for one, they
have different interface. You can say a BigInt is a superset of int but
expected<T, E> is a tool that is able to tell whether operation succeeded
or not, what reason for failure, which is something different than what T
does.

> As the intent is to naturally convey T as a wrapped return value of a
> method, the implicit construction allows "return some_t_value;" as a
> simplified syntax and the most natural one. Forcing users to use "return
> make_expected(some_t_value);" instead would be a disservice and
> discouragement, I think.
>

You may be right here. Even thoug I believe there is no algebraic argument
to back it up, it is a practical choice.

>
> (In order to imply is-a then there must be a reverse conversion operator
> from expected<T,E> to T, and that definitely should not exist, not even as
> explicit.)
>
> The caveat (and the reason make_unexpected is required) is where T and E
> are compatible, eg. expected<int, int> or expected<double, int> etc. In
> this case there is a possibility that someone intending to return an error
> value might forget to use make_unexpected and end up with code that
> compiles but is not correct. Requiring explicit make_expected does
> mitigate this case but I'm not sure it's worth the hassle.
>
> Outcome uses a different mitigation by restricting the possible types of
> E, rendering the above case very unlikely (although not impossible, since
> outcome<error_code> is legal).
>
> My question is why don't throw directly E?
>>
>> Some are requesting a way to get a specific exception from E, but either
>> there is one exception that works for all and we can set it using some kind
>> of trait or we need to add a trait parameter to expected to the the mapping
>> :(
>>
>> Do we really want this to be configurable?
>>
>
> At least where E happens to be std::error_code it would be nice if it
> threw std::system_error, since that is the exception designed for such
> things. Otherwise I have no opinion.
>
>
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman
> /listinfo.cgi/boost
>


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