On 05/25/2017 01:01 AM, Niall Douglas via Boost wrote:
First of all, I don't agree with the strong (conceptual) relationship between optional (be it boost:: or std::experimental) in such a way that expected is a generalization of it. From what I understand, the purpose of expected/outcome/ result is to be used as a mechanism to return the result of a function. As such it should also expose the semantics of it. Fortunately, we already have a (asynchronous) return object standardized (std::future). And this is my basic disagreement here: Why not model expected in the lines of future? With the main points being:
An earlier edition of Outcome did implement future-promise. I think you yourself reviewed it then.
We reviewed AFIO, which included outcome. Back then Outcome did indeed try to implement future-like semantics with semantic/interface changes which were discussed and found to be inappropriate. This is a different topic since you decided to define different semantics, again with lots of food for discussion.
- expected being movable only - expected
::value() should always return by value and invalidate this. As I mentioned in a reply to Peter yesterday, I am attracted to these semantics.
There are a lot of unanswered questions coming along with that design decision...
Second, I think Niall raised a valid about outcome being a framework for interoperability (completely orthogonal to the first point). However, I totally miss this from the proposed library, most pressing are non intrusive mechanisms. For that purpose I postulate, that a mechanism to transform between different unexpected results, that is: various error codes etc. However, for that to work, one would of course need a properly defined concept, for example, as Vicente suggested "EitherValue", and a mechanism to coerce one error type into another, maybe through ADL, or traits specialization or whatever.
already provides equivalence testing between std::error_code's.
I am not talking about equivalence testing or the ability for ones own categories. I am talking about conversions between two different error types.
Furthermore, I believe that .value/.error should really have a narrow contract, that is that it is UB to call those functions if the respective types are not held (easy to catch this in a debug build...). Why? Probably just a micro optimization, but consider the canonical usage: auto r = some_function_returning_expected(...); if (r.has_value()) // Do something with the value else // An error occurred, PANIC In both branches, we know exactly what's in there ... so why check again when getting the state out?
If you've already checked by hand, the compiler will elide the internal check entirely.
That's quite a claim to make here. When looking at vector<T>::at, this is certainly not the case, unless compilers made significant improvements over the last few years.
When I open its "landing page", I get no idea about the following: - What is the purpose of the library? - Why/when should I use it?
It quite literally tells you both on the landing page. https://ned14.github.io/boost.outcome/index.html.
From an empirical study of a non representative group, it seems it is not as literal as you would like it to be. One thing is that the points I mentioned are not visually distinguishable at first sight, there are three paragraphs with lots of prose. The first paragraph reads: "This is the Outcome library. It is a C++ 14 library intended to aid ultra-lightweight error handling in large C++ codebases, providing a more expressive and type safe alternative to integer error codes or enums." Apart from the trigger word "ultra-lightweight", what the library actually does is at the very end in a long sentence. The second: "Unlike alternative implementations, it works perfectly with exceptions and RTTI disabled and is thus suitable for low-latency/games/finance/SG14 users. One could view Outcome as a minimum overhead universal outcome transport mechanism for C++, hence being named "Outcome"." This sentence starts with "Unlike alternative implementations", I don't even know what to expect from this library, at this point, I really don't care about the alternatives yet, speaking of which, which alternatives? The key feature you wanted to highlight here is probably "works with exceptions and RTTI disabled". The next two paragraphs follow the same scheme. So in a nutshell: The Outcome library implements a set of types to be used for lightweight error transport. The main features include: - Type safe alternative to integer or enum based error codes - Works with exceptions and RTTI disabled - Suitable for real-time and low latency applications - Efficient implementation - Rich set of different types to support different use cases And then you can go on with everything else you want to say, possibly with links pointing into the documentation on where potential users are able to find more about the various topics you just advertised. (Just a braindump of mine, not claiming this is the ultimate solution.)
Niall
-- Thomas Heller Friedrich-Alexander-Universität Erlangen-Nürnberg Department Informatik - Lehrstuhl Rechnerarchitektur Martensstr. 3 91058 Erlangen Tel.: 09131/85-27018 Fax: 09131/85-27912 Email: thomas.heller@cs.fau.de