Boost logo

Boost :

Subject: Re: [boost] [outcome] High level summary of review feedback accepted so far
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2017-05-29 23:25:24

Le 29/05/2017 à 17:05, Niall Douglas via Boost a écrit :
>>> - error_type& .error_raw() - reinterpret_cast<error_type&>
>> evidently we don't like the _raw suffix.
> .error_unsafe(), .unsafe_error(), .unchecked_error() all work for me too.
How likes any of those?
Who prefers error() to throw if there is a value? or return by value and
return E{} when there is a value and I don't know hat when there is an
> For me operator*() and operator->() absolutely needs wide contracts. If
> people want the performance of narrow, they can manually write out
> excpt.value_raw()->var rather than excpt->var, or subclass expected with
> a narrow reimplementation of operator*(). It won't kill them.
I cannot agree here; operator* and operator-> have narrow contracts. We
must/should follows this design.
If you want, you can have also a named function, but please, don't
overload operator* and operator-> with similar meaning and different
>>> Outcome distinctly categorises failure-due-to-error and
>>> failure-due-to-exception. I think that important given its different use
>>> case to Expected which is explicitly for low latency and C++ disabled
>>> environments.
>> Do you mean exceptions disabled?
>> How would you have exceptions when the exceptions are disabled?
>>> But Expected as the STL type, I think your proposal is safe. Most of
>>> your users will throw exceptions for exceptional situations.
>> I guess that when exceptions are disabled, an implementation will just
>> terminate the program, isn't it?.
> Not at all. Indeed MSVC can still throw and catch exceptions with
> exceptions completely disabled so long as the throw is caught before
> leaving the stack frame in which the throw is done.
I was not aware of that.
It will be great to have probes of all the things you are saying, having
the assembler and explaining how do you deduce your conclusions.
Anyway, this doesn't help too much, isn't it? Could you give an example?
> For all major compilers, you can compile some files with C++ exceptions
> enabled, others not. exception_ptr is safe to transport thrown and
> caught C++ exceptions through exceptions disabled code. You can thus
> "bundle up" usage of the STL into islands kept separate from the rest of
> your code, and pass thrown and caught exceptions between islands of
> exceptions enabled C++ using Outcome.
I see why you could want to store an exception_ptr in this case. I
wonder just how often do we find it.
>> I can not ignore this Outcome review, but I have not see too much people
>> saying that the semantic you have done to this functions is the good one.
> Strange. I've been surprised at how little criticism there has been of
> my design choices. Silence can be interpreted both ways I guess.
he he, you find that your library has not been criticized?
>> Nevertheless I will add an open point about having narrow and wide
>> contract for the error access.
>> I will add also another open point to have the possibility to return E{}
>> when the contract is wide instead of throwing an exception.
>> IMHO we need just the narrow contract function. The other can be built
>> on top of this by the user or by Outcome.
>> Remember Expected proposal has already two open_points for
>> err error_or(exp, err) and
>> bool has_error(exp, err)
> I do agree with this philosophy, but if you're going to go narrow, you
> need to go narrow on everything including .value(). You need to
> consistently choose one or the other. No middle ground.
value() id wide operator*() is narrow.
> An advantage of all narrow is you can eliminate bad_expected_access and
> simplify the Expected proposal to be merely a thin API convenience layer
> wrapping std::variant. A separate std::result, as Peter suggested, can
> layer on top of std::expected with all wide observers as would make much
> more sense for an object returning uncertainty. But it's up to you.
I'm not against the the wide functions. I'm against not having the
narrow one.
>>>> What your checked_outcome<T>::error will return if the is a
>>>> exception_ptr?
>>> Ah, finally someone brought this up. Good!
>>> It returns an error_code with bad_outcome_category and
>>> bad_outcome_errc::exception_present.
>> Ugh. Why your design is never coherent. Why you don't name your
>> functions after what they do?
> I would call my design asymmetrical. I can see why some would call it
> incoherent.
I believe that we want to know what a function does when we see a name
that is used already.
I call this coherency. Having functions that use the same name and that
they do different things is not asymmetrical for me.
>> What if the exception_ptr contains an arbitrary exception? No way to
>> obtain an error_code :(
> There is a macro to do that in the presented library. Peter has
> discovered it to be over engineered given current compilers, and so
> will replace it.
I see that Andrzej has responded in your place elsewhere. So you will
use a single error code in this case, isn't it?
More I know about your library more I find it wired.

We can consider expected<T,E> as a Nullable type, but I will not because
I will not make all the error values to be considered as a single null


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