On Fri, May 29, 2020 at 1:26 AM Alexander Grund via Boost < boost@lists.boost.org> wrote:
Maybe improve on `remote_handle_all` in 2 ways: Create the lambda taking `leaf::error_info const&` in that function to remove the boilerplate at the user call site. Given that rename it to e.g. `create_remote_handler` or so. I find the current interface confusing and the documentation calls it "unintuitive", so I guess this should be improved on before release. Given that: It seems `remote_try_handle_all` can be folded into the regular `try_handle_all`. So `try_handle_all` takes a list of handlers where one could be the aggregated handler defined by `create_remote_handler` (then maybe `create_aggregate_handler`?)
I've explored folding it all into try_handle_all, but the implementation gets really messy. Perhaps it can be done. Consider that in this case the loop that matches the lambdas based on what error objects are available at runtime now has to be recursive. Maybe it can be done elegantly, but I tried and gave up.
I'm interested in knowing how `try_handle_all` implements "if the user fails to supply at least one handler that will match any error, the result is a compile error". If arbitrary functions can be called throwing any error type, how could that work? Is it again required to use a catch-all clause?
Yes, you must supply a handler that matches any error. If you don't want to do that, use try_handle_some. The benefit of _all is that it unwraps the result for you: where try_handle_some returns a result<T>, try_handle_all returns T. It also guarantees at compile time that the user has provided a suitable handler for all errors.
- What is your evaluation of the documentation? Good overall, but the details are to detailed for an introduction and to coarse for understanding it.
Thanks for this feedback.
- "Using Exception Handling": virtual inheritance is mentioned but the reasoning is not clear to me. I have never used or seen it used in that context and always strive to avoid it due to the issues with handling such an object (starting at writing ctors)
This is a somewhat-known problem with exceptions. If you have: struct A { }; struct B1: A { }; struct B2: A { }; struct C: B1, B2 { } Now a catch(A &) won't intercept a C because the cast is ambiguous. Using virtual inheritance eliminates this problem and allows A to be safely used as a base of anything that should be classified as A.
- "Accumulation": shows how to call leaf::accumulate but I don't see what it use is. "Many different files" are mentioned but the operation only takes a single file. And based on everything before a single error stops execution (like exceptions)
Normally you give LEAF an object of type T and it stores it away for you. If you later give it another value of type T, it'll just overwrite the old one. With accumulate, you get a mutable reference to the stored value (and it requires T to have a default constructor).
- "error_id": It is unclear to me what it's use is. Especially as something unique in the program in the context of threads means some kind of synchronization which will be paid for even if unused.
See https://zajo.github.io/leaf/#tutorial-model
- "defer": I'd like to know when the lambda is not called. The documentation says it is called in the dtor, but later: "function passed to defer, if invoked,"
The logic is the same as for preload, which takes your value, and will later communicate it if an error has occurred, while defer takes your lambda and will later call it to get a value to communicate, if an error has occurred.
I'd also like to see a comparison with exceptions especially in cases where the usage of result<T> inhibits (N)RVO (even more for C++17 and up). This is my main critic point about result<T> type of error handling as that variant type creates less efficient code for the happy path.
Yes, though leaf::result<T>, in case of an error, only transports a single int, the error_id, which allows for efficient implementation. That said, you can use pretty much any result type with LEAF, it does not have to be leaf::result<T>. Thanks!