Boost logo

Boost :

Subject: Re: [boost] [outcome] narrow-contract, wide-contract, and value_if
From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2017-05-31 06:50:09

2017-05-31 1:30 GMT+02:00 Gavin Lambert via Boost <boost_at_[hidden]>:

> 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<T,E> 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.


Boost list run by bdawes at, gregod at, cpdaniel at, john at