
On Fri, Feb 2, 2018 at 1:19 AM, Niall Douglas via Boost < boost@lists.boost.org> wrote:
In contrast, Boost.Outcome is intended for usage in these rare cases were "forward up and abort" is not the thing you would like to do most of the time. Its goal is not to handle failures anywhere, but to solve a specific problem in specific places. I believe that the criticism of Boost.Outcome should be in this context of places where "forward up and abort" is not what you typically need to do.
And this really drives to heart of what I don't get about your arguments Emil. Outcome is really an abstraction layer for setting per-namespace rules for when to throw exceptions. Exception throwing is absolutely at the heart of Outcome. That's why Outcome != Expected, and why it ICEs older compilers, and why C++ 14 is needed.
Consider the following library: template <class T,class E> class result; //contains variant<T,E> conversion to bool returns true if result was initialized with T, false otherwise; .value() returns T& or calls boost::throw_exception(error()); .error() returns E& or undefined behavor. You could use this library together with exception handling: it helps with annoying exceptions when you can handle the error locally, otherwise you just call .value() and let exceptions do their thing. The question is what to do under BOOST_NO_EXCEPTIONS. Presumably you could go with E=error_code, but that is inadequate for forwarding arbitrary errors, making the library impractical to use without exceptions -- and we want a library that is practical to use without exceptions. Correct me if I'm wrong, but I think that you and I agree on this. So, my vote is based on (in no particular order): 1) In these discussions, I can clearly recognize the dislike for exception handling and even C++ (I don't mean by you personally) that I have been exposed to in the past, since for years I've been surrounded by people who falsely believed that they can't afford exceptions or smart pointers or proper serialization, and they have strong, if incorrect, opinions on what's wrong with C++. I believe that this attitude does not belong to Boost. It's possible that I got this wrong. It may be interesting to know how many of the current users of "standalone" Outcome use Boost in "low latency" environments or at all. Do you have an idea? 2) Clearly, Outcome _does_ want to help pass errors across API boundaries, including in generic contexts. The problem is that result<T,E> compute() noexcept; is very similar to T compute() throw(E); (yes, I know exception specifications are enforced dynamically, but that's not what's wrong with them, see the second question here: https://herbsutter.com/2007/01/24/questions-about-exception-specifications/ .) My reasoning is that if with Outcome you can always return the exact error type you've specified in your static interface, the same approach would work for (perhaps statically-enforced) exception specifications. Logically, to address this concern you could: - Demonstrate that there is a major flaw in my analogy, or - demonstrate that exception specifications could be made practical, including in generic contexts, possibly by using some clever policy-based design, or - provide an interface that can forward arbitrary errors ot the caller. (I see these as mutually-exclusive).