2017-05-31 1:30 GMT+02:00 Gavin Lambert via Boost
On 31/05/2017 10:36, Andrzej Krzemienski wrote:
First, the wide-contract functions.
We have a situation when someone assumes that `o` currently stores an error_code, and with this assumption in mind calls `o.error()`, but somehow his assumption is incorrect. What do we want to do?
1. Try to report programmer's bug at run-time? 2. Since in this case it is a bug anyway and are screwed, at least let's make such behavior useful for other situations where `error()` is called conciously on `o` without an error code?
Perhaps this is where our philosophical difference lies.
I don't consider calling error() a bug *at any time*, even if the object does not explicitly contain an error_code.
An outcome is *not* a variant and does not have the same semantics as one.
(Having said that, this argument applies only to result/outcome, where the error type is known and can be sanely constructed to indicate "no error occurred". expected
can't make that assumption so it's much more like a plain variant. This is actually one of the things I dislike about expected.) The second scenario in a way ignores the bug, and lets the program
continue, as though it was correct, and from now on the program is doing something else than what the programmer intended. But the semantics of the function are useful in itself. Users who check `o.has_error()` before calling it can use it as if `error()` had a single purpose and a narrow contract; and users who know the additional semantics can use it for other useful things, like saving themselves of writing some boilerplate code.
What if the programmer intends to get an error_code that indicates success, perhaps for logging purposes? Like I said, this should not be considered a bug in the first place, and the program *is* correct.
I guess I was not able to convey my reasoning as clearly as I would like to. I know what you are saying. You want to have a function in the interface that returns a non-zero error_code when, when `o.has_error()` and a zero-error when `o.has_value()`. There is a demand for it, `outcome` should provide for it, this way or the other. On the other hand, because the current names go in pairs (has_valeue() and value(), has_error() and error()) that someone can get the the mental model of a `variant`. Because of all the confusion reported in this review, my suggestion would be to indicate clearly which of the observers is just a `getter` for one of the variant states (possibly with run-time checks), and which is a "convenience" function (which may observe more than one variant state). And once you indicate it in the docs, maybe also indicate it is the function name. This way `error()` would mean "observe the state of the variant (or sum) element corresponding to `has_error()`, ans `as_error()` would say "interpret the entire `outcome` as an error_code". f course I am still not sure how error_code and exception_ptr mix in these functions, so I may be confusing some people. Regards, &rzej;