Boost logo

Boost :

Subject: Re: [boost] [gsoc-2013] Boost.Expected
From: Michael Marcin (mike.marcin_at_[hidden])
Date: 2013-04-23 17:57:01


On 4/23/13 3:43 PM, Gottlob Frege wrote:
> On Tue, Apr 23, 2013 at 3:28 PM, Pierre T. <ptalbot_at_[hidden]> wrote:
>
>> Le 23/04/2013 18:55, Gottlob Frege a écrit :
>>
>> We can throw anything we want. I'm not sure it is a good idea, but you
>>> can
>>> throw anything. It doesn't need to derive from std::expection, for
>>> example. You can throw an int. etc.
>>>
>>> Of course, but I guess it's a bad practice ?
>>
>>
> I'd agree with that.
>
>
>>
>>> What we did for optional<> is allow you to access the value in 2 ways:
>>>
>>> optional<int> oi;
>>>
>>> int x = oi.value(); // throws bad_optional_access
>>> int y = *oi; // undefined behaviour
>>>
>>> Similar to vector [n] vs at(n).
>>>
>>> We could use something similar in expected. But we must keep in mind
>> that expected has a value and an error, is it clear that *expect return the
>> value and not the error ?
>>
>>
> Yes. It is called "expected" after all. You expect the value, not the
> error. And if there is an expect.is_valid() I expect it to be referring to
> whether the value is valid, not the error. Etc. It is not called
> "std::pair<Value,Error>", it is expected<Value,Error>.
>
> IMO, at least.
>

It seems to me that if you're using this expected class, you're
expecting an error, at least some times. Otherwise why wouldn't you just
throw.

FWIW I think the OP's idea of separating out the error handling code
from the error site is misguided here. This isn't exceptional flow it's
part of the normal expected behavior.

If you're using it to parse user input for instance handling invalid
input to me seems directly applicable to the task at hand even if it
must be propagated a short ways to be handled.

.
>
>
> But I lean towards thinking that Error is rarely or never an exception - if
> it was, why use expected<> at all? Just throw the exception. I think of
> expected<> as being used in places where you don't want to use exceptions.
> ie if you have
>
> expected<int, SomeException> someFunction();
>
> where someFunction() could *return* an exception, why not just
>
> int someFunction(); // throws SomeException
>
>
> So I think I'd prefer it always to wrap. ie assume that the Error is NOT
> an exception, and not meant to be thrown. The only time it is thrown is
> when someone (mistakenly? ie coder error) accesses the value via
> expect.value() and it throws bad_expected_access<Error>. Or
> "un_expected_access" :-)
>

Seems a lot like a code error to me.
Might as well just throw std::logic_error if you're going to implement
the anti-pattern. If you're going to specify what happens at all here
you might as well std::terminate.

Personally I would prefer leaving the behavior undefined.

>>
>> What others think about this behavior and interface ?
>>
>> Thanks for any comments.
>> Pierre Talbot.
>>
>>
> I'd definitely like to hear more from others. Maybe I'm not imagining some
> of the ways this is expected to be used.
>

I dislike expected's type not encoding what errors it the user should be
expected to handle.

In many ways it seems worse to me than returning a variant like
variant<result_type,error1_type,error2_type,...>

You could always (i think) return variant<result_type, any> if you
wanted to avoid specifying the errors for some reason.


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