Boost logo

Boost :

Subject: Re: [boost] [outcome] Second high level summary of review feedback accepted so far
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2017-06-08 22:53:52


On 8/06/2017 23:36, Niall Douglas wrote:
> It doesn't especially help you in practice. What Outcome currently does
> is return magic type sugar from TRY which is implicitly constructible by
> any basic_monad instance, this works around needing to know what the
> return type is for the calling function in the TRY implementation.

Fair enough. That could still work for arbitrary EI types though -- you
automatically know what the type used by the method you're calling is,
and you can assume that the caller either returns the same thing or
something compatible with it, as I said below. Otherwise it will be a
compiler error, and rightly so.

>> Besides, if the intent is to convey the payload up the call chain, then
>> it can be left to the responsibility of the method itself to forward
>> that appropriately -- ie. if you call something that can return an
>> error_code_info<EI1> then you are required to do one of the following:
>>
>> 1. Deal with the error locally, not calling TRY.
>> 2. Call TRY to pass on the error unmodified, thereby requiring that
>> you also return an error_code_info<EI1>.
>> 3. Pass on the error, but returning error_code_info<EI2> where EI2 is
>> constructible from EI1 (forwarding the original payload plus some
>> additional context). This might be a special case of #1.
>>
>> (By "returning" here I don't mean directly, I mean wrapped in a result<>
>> or outcome<>.)
>
> Of course you could do all that.
>
> What I'm saying is that for 95% of programmers, when facing the choice
> of whether to use different E types in exchange for typing a ton load
> more boilerplate all day long every day in everything they write, they
> will - I guarantee you - choose just to make the error type the same
> throughout the entire program. It makes things *simple*.

People don't seem to have a problem with multiple exception classes
carrying different payloads all derived from std::exception. This is an
orthogonal idea, albeit simplifying it with only a single templated
derived type. (I'm not opposed to having separate derived types either,
but I think the templated design is better since you can provide better
guarantees to the outcome implementation.)

I don't think it'd be as hard to grasp as you're making out. If we take
Filesystem as an example, it's likely that most methods would return an
error_code_info<filename_info> that contains the filename affected by
the error (which you might argue is useless to the caller since it
already knows, but again imagine this being bubbled several levels up
the call stack to code that didn't know the filename any other way).

A few might return a plain error_code because they didn't have a
filename to work on. Something like copy_file might return a type
derived from filename_info that adds a second filename. That sort of thing.

Or maybe Filesystem itself would only return plain error_codes, but then
the caller (who constructed a filename unknown to the grandparent) might
be the one that wants to include the actual filename when passing on the
error, since it knows that its caller has no other way to know it.


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