Boost logo

Boost :

Subject: Re: [boost] [outcome] High level summary of review feedback accepted so far
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-06-01 18:33:35


On 01/06/2017 00:35, Gavin Lambert via Boost wrote:
> On 1/06/2017 08:17, Niall Douglas wrote:
>> The programmer, when working with outcome<T>, knows that calling
>> .exception() will return the exact same exception as would be thrown
>> when calling .value(), thus saving wrapping .value() in a try...catch
>> just to capture the exception_ptr emitted.
>
> Except empty. value() throws that as an exception. exception() also
> throws that as an exception (not returning it), which means that the
> programmer can't make that assumption you just claimed.
>
> Maybe that's what you want (as it leads very quickly to empty ==
> std::terminate), but it's not consistent with use of empty as a success
> return as you've suggested in a few places.

Empty is supposed to have the severest, most abnormal default actions.

>> For result<T>, it's basically a castrated outcome<T> used only for
>> performance sensitive code, or rather, to say "this function takes
>> performance very seriously".
>
> From the docs and discussion thus far, this is not the impression I had.
>
> The impression I had was that result<T> should be used everywhere in
> inner exception-enabled code by preference (since exceptions should not
> be caught, they should be propagated outwards).

That's one approach. But definitely not the sole one.

result<T> may also be returned from any function which solely calls STL
exception throwing code. Indeed, Outcome provides a catch-to-result
macro just for that. This lets you call STL code easily from within
noexcept-land.

> And then up at the entrypoint from the sea of noexcept to the
> exception-enabled island, that entrypoint (which is itself noexcept)
> should return an outcome<> from the result<> of its children or an
> internal try-catch to propagate out an exception_ptr.

This part is often the case.

> outcome<> is used
> almost exclusively within the sea; result<> only rarely (for cases where
> an exception cannot occur).

Not necessarily. In my own code to date, I've mostly used outcome<> in
exception throwing land and result<> in noexcept-land. But you're right
that in most code bases, you probably would use outcome<T> for that yes.

> Further up the call stack (back in exception-throwing land) you receive
> an outcome<> and immediately unpack and rethrow any exception, or
> otherwise go back to returning result<>s.

Yes, but don't forget result<T>.value() throws the exact same exception
as outcome<T>(result<T>).value().

Certainly when using AFIO v2, I find myself writing a lot of
afio_function().value();. I really wish it were more permissible to
throw from destructors, then if the return were errored and you don't
deal with it, it throws, no .value() needed.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

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