Hi Niall, Here's my feedback. It is on the documentation alone. I do not comment on the usefulness on the library here. After a conversation with you in another thread I think I understand the scope and the value of the library. It is also my impression that the initial page of the docs does not reflect it clearly enough.
Bah I'd forgotten to commit the updated v3 rewrite edition of that initial page. Sorry. Here's the initial page now:
This is the Outcome library, a Boost C++ 14 library providing an implementation of expected
(which is on the C++ 20 standardisation track), with refinements of expected for large C++ codebases outcome<T> and result<T>. Its main intended usage is as an ultra light weight error handling framework, providing a more expressive and type safe alternative to error code integers or enums, yet much lower overhead than exception throws. Unlike alternative implementations, it works perfectly with exceptions and RTTI disabled and thus is suitable for low-latency/games/finance/SG14 users. One could view Outcome as a minimum overhead universal outcome handling framework for C++, hence being named "Outcome". If you are familiar with Swift's error code throws or Rust's Result<T>, you will find almost identical semantics in the transports provided here. One can therefore write systems programming code using these transports in C++ in the same design pattern as when writing in Rust or Swift, and with a similarly low runtime overhead. Outcome even has a BOOST_OUTCOME_TRY macro doing most of the try keyword in Rust and Swift!
Back to your feedback:
- We will be dealing with some factory (but do not know why) - There will be some policies (what for? Do I need to know about them at this point?)
Any mention of factories or policies is being excised from the documentation right now.
- There will be monads involved (word "monadic" used), and, not being a Haskell expert, I have been informed in many blogs, that "monad" is a quite difficult concept to comprehend.
I'm currently in the process of purging all mention of "monad" too in the docs.
After the first sentence, I am concerned that there is a number of things I already do not know (transports, monads, policies), these will probably prevent me from understanding the rest; and I still do not know what the library is for. But now I am more irritated, and less motivated to dig further.
If your irritation is now improved, what do you think of the new and
completely rewritten for a third time tutorial part A at
https://ned14.github.io/boost.outcome/md_doc_md_02-tutorial_a.html. Part
A is 100% a tutorial on LEWG Expected and has nothing to do with Outcome
at all. Part B will be on why you shouldn't do all the things you think
you should do with expected
Second sentence talks about "error handling framework". I am not sure if name "framework" fits here. The only useful information is that it deals with "error handling". Better than enums: ok. "Lower overhead that exception throws" -- in the other thread you mentioned that the main motivation was not to outperform exceptions, but to make the control flow more explicit.
Good point. I'll remove the mention of overhead.
"If you are familiar with Swift's error code throws or Rust's" -- I think it should go to the end of the page. I am not familiar with Swift or Rust, and after monads, transports, policies, the feeling of being alienated gets reinforced.
A very large part of this library's userbase wants this stuff from Rust
and Swift into C++. You should have a look at the Reddit threads. I've
also got quite a bit of private email on the topic. Lots of very
enthusiastic people for expected
The example does not illustrate that we are "dealing" with the framework. It only illustrates that we have a new type `outcome<int>`.
You make a good point that "framework" is confusing. It's a good suggestion to remove mention of frameworks too. I will do this.
Maybe for an introduction, it should read something like:
<blockquote>
This library provides a type that can represent a function's output, which can be either of the three:
- The value that the function was intended to produce, - An error condition that requires to be handled locally, - A fatal failure that cannot be handled locally (and may even result in program termination).
In addition, this library comes with a handful of operators and a control statement in a form of macro BOOST_OUTCOME_TRY() that make the task of inspecting, unpacking, and conveying the outcome up the stack easy and concise.
This library is useful for:
1. Discriminating between "local/expected" and "fatal" errors, and 2. For assisting the programming style, where expected/local error conditions are explicitly handled locally, or explicitly passed up the stack.
</blockquote>
This is a nice description. Thank you. But as you'll see in v3 of the docs, I've completely rearchitected the message. Now Outcome looks like it's primarily an implementation of LEWG Expected, and it provides a few refinements of Expected which most users won't care about or will refuse to use.
In addition to the example that is already there, I think it would be beneficial to see, still in the first page a short example how an error is conveyed up with macro BOOST_OUTCOME_TRY().
I'm very hesitant to use that macro in an example without explanation of its semantics. Tutorial part B explains it.
Ok, I stop now. It came out loner that I expected. I hope this helps, though. &rzej;
Not only has your feedback and discussion been very valuable, I don't think the v3 tutorial would look like it does now without you. Do let me know if the v3 tutorial now makes sense to you. I even dove into "noexcept as can't fail" vs "noexcept can fail" as a nod to you :) Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/