Boost logo

Boost :

Subject: Re: [boost] [outcome] Review of Outcome
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-05-28 23:46:59


> In my opinion the library should drop option<T> and result<T> altogether
> and should be reduced to outcome<T> only, which can be empty, or hold a T,
> or hold an exception (but not error code, see below.) This is critical for
> a library that aims to provide a _common_ general mechanism for dealing
> with failures in interfaces; providing a rich set of alternatives works
> against that goal.

As was covered in the FAQ, outcome<T> may store an exception_ptr, which
is implemented using atomics. This causes the compiler to emit a lot
more code than a result<T>, which is why we have a result<T> with
implicit conversion on demand to an outcome<T>. If one uses the least
representative type possible, one gets minimum code bloat and maximum
performance.

> Secondly, it is not a good idea to use error codes or any other value as
> means to dispatch on different kinds of failures because semantically such
> dispatch should be static: there is some _code_ which detects the error,
> and there is some other _code_ that needs to bind it and handle it. This is
> one reason why in C++ catch dispatches by the static type of the exception
> objects, not by some exception.what() value.
>
> Further, using static types to communicate different kinds of failures
> allows users to recognize and handle an entire class of errors by means of
> implicit type conversions, by organizing error types in a hierarchy. For
> example:
>
> struct io_error: virtual std::runtime_error { };
> struct read_error: virtual io_error { };
> struct write_error: virtual io_error { };
> struct file_error: virtual io_error { };
> struct file_read_error: virtual file_error, virtual read_error { };
> struct parse_error: virtual std::runtime_error { };
> struct syntax_error: virtual parse_error { };
>
> With this hierarchy, we can use read_error to handle any kind of read
> errors (not just file-related), file_error to handle any kind of file
> failures (read or write), etc.

If you favour using the type system to statically enforce error codes,
then expected<T, E> is exactly the right object for you.

> III. Documentation
>
> The documentation makes broad claims about the inefficiency of exception
> handling which seem to be motivated by a desire to appeal to programmers
> who hold such beliefs. There is no need to make such generally untrue
> claims in order to justify the need for Outcome.

As I told you when you raised this originally, no such claims were ever
made. I made a specific claim only - with benchmarks - about the
relative cost of an exception throw and catch to returning an integer
error code or an expected<T, E>.

I have repeatedly stated during this review on numerous occasions that
when using Outcome/Expected, you are generally exchanging some
performance during success for much improved performance during failure.
It's a zero sum exchange.

> Should Outcome be accepted into Boost? NO
>
> This obviously applies only to the current state of the library.

Would you be able to list changes you would consider minimum to change
your vote to a YES?

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