2017-05-28 11:35 GMT+02:00 Vicente J. Botet Escriba via Boost < boost@lists.boost.org>:
Niall I'm trying to see what you want to propose by difference to a hypothetical generic interface to see what is the added value.
Le 27/05/2017 à 16:13, Niall Douglas via Boost a écrit :
- outcome<T> and result<T> will have their empty state removed, and all
observers gain narrow contracts. Default construction is disabled. https://github.com/ned14/boost.outcome/issues/44. Example:
``` result<Foo> v(make_errored_result(std::errc::invalid_argument)); assert(v.has_error()); // true assert(!v.has_value()); // true // As if Foo(reinterpret_cast
// (error_code_extended(std::errc::invalid_argument)); Foo f(std::move(v.value())); assert(v.has_error()); // still true assert(!v.has_value()); // still true ``` Just a question I could do for the existing library also. What has_error mean for outcome, result? is that it has an EC or that it has no value?
.has_error() is true if and only if the current state is an error_code_extended instance.
Okay. Why don't you name it has_error_code? For me having an exception_ptr stored was also an error.
Why not name the getter error function get_error_code, .... as the function doesn't returns a generic Error but one of them.
I don't think using the same name for different things is helping in generic programming.
And now that we don't have empty, what is the sens of has_error for
result?
There will be no longer an empty state in result<T>, but for generic programming I'll be retaining a .has_error() so end users can more easily swap a result<T> for a result_e<T>.
:(
I see generic programming in other terms.
Maybe, outcome should have a get_state function that returns an enum so
that the user can do a switch.
I had previously a .visit(callable) for that.
Any sum type should provide a visit function. I've implemented it in the std_make repository. I will add it to Expected proposal once we have a SumType type of classes.
(NOTE: expected
will track whatever LEWG Expected does, but it differs from what will become result<T> by having a wide contract on .value() and narrow contracts on operator*(), .error(), operator->(). result<T> will have narrow contracts on everything, it is basically a thin wrap of std::variant
except with strong never empty warranty) What will be the differences between result<T> and expected
? The wide contracts for the observers? Can not we provide wide and narrow contracts or don't reuse the same name with different meaning?
The description above quite literally tells you the differences.
Why we cannot provide wide and narrow observers? If this is the single difference I don't see the need for having two types.
If we had a expected
what will be the differences between outcome<T> and expected
? I would assume an expected
could only return a std::variant from its .error(). I can't think what else it could do. This function *could* return variant
or variant or any sum type that represents the error, that is the Not-A-Value. Maybe, expected
::get_error<Ek> could be more useful. In any case expected
should provide a visit() function. Having more than one Error makes this absolutely necessary. When having more than one error in expected, having access to each one of them using a different interface would make the user code more complex, isn't it?
outcome<T> continues to provide:
- T& .value() - error_code_extended .error() - std::exception_ptr .exception()
i.e. hard coded.
Ok, so the single difference would be about the error observers returning by value and having an explicit name.
- New typedefs outcome_e<T> and result_e<T> are identical to outcome<T>
and result<T> except for adding a formal empty state. Observer contract slightly widens, an attempt to use an empty object throws a bad_outcome_access exception. Implicit conversion from non-empty-capable varieties is permitted to empty-capable varieties, but not the other way round. Default construction is to **empty**. https://github.com/ned14/boost.outcome/issues/44
Okay this corresponds to what others are naming optional_outcome, optional_result.
I'm not wedded to result_e<T> etc. Ok, I'll change result_e<T> and outcome_e<T> to optional_result<T> and optional_outcome<T>. Done at https://github.com/ned14/boost.outcome/issues/44
Neither me. Just wanted to name the types in a more explicit way. result_e doesn't tells me the intent.
If we had a optional_expected
what will be the differences between result_e<T> and optional_expected
? what will be the differences between outcome_e<T> and optional_expected ? I am not sure what semantics you have chosen for optional_expected<>.
optional_expected
should be an optimize version of optional >.
According to Niall's example, it was my understanding that his mental model
was `expected