2017-01-11 13:53 GMT+01:00 Niall Douglas
Dear Boost,
Last November you gave me some valuable feedback on rewriting the tutorial for Boost.Outcome, a C++ 14 library providing a factory and family of policy driven lightweight monadic value-or-error transports. I recently came out of employment contract and so have had the time to rewrite Outcome's Tutorial (anyone interested in employing a remote working C++ consultant please do get in contact). I'd appreciate feedback on https://ned14.github.io/boost. outcome/:
1. Is this rewritten tutorial too simple, too detailed or about right?
2. Do you feel you could use Outcome in your own code without difficulty after reading it? If not, what information is missing?
3. Are you persuaded of the merits of using Outcome after reading it? If not, what else do I need to say?
The first FOUR sections at https://ned14.github.io/boost.outcome/ have been rewritten by me to hopefully reflect the feedback you gave me last November, so these have been refactored so far:
* Description, Prerequisites and Support * Installing, building and testing Outcome * Quick start for the expert * Tutorial
The package repo install methods haven't been implemented yet, these are marked in the docs as todo.
These sections have yet to be refactored:
* Frequently Asked Questions * Advanced usage: Outcome as a Monad * Outcome and the upcoming std::expected
Many thanks in advance for any feedback received.
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. The very first paragraph goes like this: This is the Outcome library, a Boost C++ 14 library providing a factory and
family of policy driven lightweight monadic value-or-error transports with the convenience simple specialisations of expected
, outcome<T>, result<T> and option<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.
I learn from this that: - 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?) - 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. - There will be "transports". I am not a native English speaker, and I am confused here. What is a "transport" as a noun, in the context of programming? - There will be many specializations. But I do not know why and what for at this stage 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. 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. "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. The example does not illustrate that we are "dealing" with the framework. It only illustrates that we have a new type `outcome<int>`. 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> 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(). Ok, I stop now. It came out loner that I expected. I hope this helps, though. &rzej;