Boost logo

Boost :

Subject: Re: [boost] expected/result/etc
From: Domagoj Saric (dsaritz_at_[hidden])
Date: 2016-02-07 12:49:27


On 5.2.2016. 10:25, Niall Douglas wrote:
> On 4 Feb 2016 at 23:02, Domagoj Saric wrote:
>
>>> You could theoretically pass exceptions function-to-function by
>>> exception_ptr but that seems backwards, no pun intended. :)
>>
>> And we could theoretically and practically ;) return actual error
>> objects (even those considered 'exceptions', e.g. std::runtime_error)
>> w/o necessarily stuffing them into some type erasing mechanism like
>> exception_ptr (i.e. you pass the ball as a ball until you need to
>> interact with someone who only understands abstract UFOs;)
>
> exception_ptr is like shared_ptr - the potential use of atomics
> forces the compiler to emit code just in case. Any potential use of
> atomics is like calling fsync() on the compiler's AST.

That's (in line with/part of) my point?

> Firstly I just found and read your RFC on this potential Boost.Err at
> http://lists.boost.org/Archives/boost/2015/11/226558.php. You posted
> this during my vacation away from Boost, so I didn't see it till now.
> I'd like to thank you for this contribution to the debate, it
> certainly is original.
>
> There are some very interesting - perhaps even debatable - feature
> choices in this object. I'll skip commenting on most of those, but I
> will say one thing - I've found in AFIO v2 the ability to use
> outcome::result<T> as a receiving container surprisingly useful. The
> pattern looks like this:
<snip>
> In other words, I found my result<T> very useful as a state
> accumulator which can "go errored" in a natural way.

Can you elaborate more on what you mean by "state accumulator" and
"going errored in a natural way" in this context? + you seem to be using
'container' and 'accumulator' interchangeably while AFAIK those are not
eqivalent concepts...

If by 'state accumulation' you imply the requirement that the result<T,
E> object (R from now on, as a short unifying 'meta name' for this
'result' object that we've all named differently) be mutable either in
the limited sense (only that the contained error, E, object, if any, be
mutable) or in the full sense (that the R object can be switched from a
'succesfull-so-far' to a failed state, i.e. that the contained T can be
destroyed and an E constructed in its place) then yes Err's
result_or_error and fallible_result do not support it:
- in the case of fallible_result, as an 'rvalue only' type, this makes
no sense
- in the case of result_or_error this is, for the most part, merely an
API decision/restriction.

For the 'limited sense' I can merely add the non-const "Error &
result_or_error<>::error()" getter so one can manipulate the contained
error object (if there is one, i.e. if the RO is in the failed state).
For the 'full sense' I'd have to make the result_or_error object
assignable, which in turn would require making the state flags non-const
(and hope this does not affect the optimiser).
However, the reason things are the way they are is narrowing the scope:
the two central Err types are meant to solve one, and only one, problem:
providing a generic, efficient and safe packaging for transporting
function call results (failed or succesfull) and are always meant to be
part of a return statement.
Cumulative and/or asynchronous results/operations (future-promise kind
of thingies) are IMO better implemented on-top of such lower level
primitives - i.e. concepts like fallible_result should not even
implicitly mention/model in their API such specialized solutions
(cumulative, async, etc. result) but should enable their efficient
implementation...

> Your Err object can't do value semantics - it cannot be a container
> in its own right. I personally think that is unfortunate for the
> reasons above. I think there is much more usefulness in these objects
> having full value semantics BUT with a restricted variant content,

I don't know what you mean here:
* there is no 'Err object', there are two types - fallible_result and
result_or_error[1]
* both of those carry Ts and Es by value

> so
> basically either it's the value you want OR it's why there isn't a
> value you expect there.

AFAICT that's exactly how the two Err objects work..?

[1] it 'dawned' on me a few days ago that the langauge change/addition I
already 'requested'/wished for (rvalue destructor 'overloads') would
also enable that the two types (fallible_result and result_or_error),
could be merged (as esentially their only major difference is
on-destruction behaviour)...

-- 
"What Huxley teaches is that in the age of advanced technology, 
spiritual devastation is more likely to come from an enemy with a 
smiling face than from one whose countenance exudes suspicion and hate."
Neil Postman

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