Boost logo

Boost :

Subject: Re: [boost] Outcome v2
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2017-07-11 19:43:41


On 11/07/2017 18:13, Emil Dotchevski wrote:
> On Tue, Jul 11, 2017 at 1:08 AM, Niall Douglas via Boost
> <boost_at_[hidden] <mailto:boost_at_[hidden]>> wrote:
>
> outcome<handle, std::error_code, std::filesystem::path>
>
> ... could return an open file handle on success, or an error code plus
> the failing path on failure.
>
>
> The third parameter, "error info", should not be specified by the error
> reporting code because what info is relevant to a failure depends on the
> context, which is not know an the point you report the error.

That *may* be the case, but it is not always the case.

In the case of say a file rename operation, it's very reasonable to
supply error context info of the two paths involved. Like
std::filesystem_error does. For such a rename() function, sure you'd
hard code the error info type.

> As you saw on SG14, using any black box library routines is always going
> to be a problem for the fixed latency user base.
>
>
> What is a black box library routine? If you're referring to the use of
> TLS, like I said in that thread, it's a constexpr constructor so there
> is nothing to initialize and no reason for the TLS to be slow. Nobody on
> SG14 challenged this point, so I'm not sure what you're referring to.

I think that nobody *bothered* to challenge you. That's very different.
They indicated misgivings with that design choice, you did not
acknowledge them in a way they felt indicated you were open to being
corrected, so they said nothing. Happens all the time on boost-dev too
of course.

Personally speaking, I actually don't know in truth. I just feel deep
suspicion. TLS used to be awful unpredictable latency some years ago,
only Windows's TlsAlloc() was sane, and it only had 64 slots for the
entire process which was easy to exceed. But C++11's thread_local has
forced significant improvements. I know what those are in theory, but
I've done no deep dive into individual, specific implementations. I'm
pretty sure most, if not almost all, on SG14 are in the same boat. C++
11 thread_local implementations are too new yet.

A really great CppCon talk topic would be benchmarking and poking with a
stick the three main thread_local implementations. Easily a full hour.

> Your library is shorter
> than mine, but it calls unknown latency routines. Mine never does.
>
>
> That was addressing your offer to use Outcome as a "building block" for
> Noexcept. The point is, the "building block" is heavier than the
> "product". :)

More lines of code has little to do with heaviness. I got some flak off
Reddit regarding Outcome v1's length in line count. Totally irrelevant
to compile time load.

> You also impose TLS on your end users. Mine is much lower level than
> that, if end users wish to combine mine with TLS to achieve your
> library, they'll find it very easy.
>
>
> It's the other way around, actually. The use of TLS moves the error
> objects off the critical path and removes the coupling between errors
> and error-neutral contexts. These are Good Things.
>
> The decision to force users to enumerate their error types (recall again
> exception specifications) and to move errors up the call chain one level
> at a time should be justified and supported with data showing that
> thread_local is too costly in practice.

You're forgetting one of the primary reasons to use an Outcome/Expected
type is deliberately encode failure handling near the point of failure.
People specifically want to see the handling code there so it can be
audited and writing it cannot be moved elsewhere. So you want those
error types in there to force the issue.

> And the thing is, there is no reason for it to be costly. If it helps,
> think of it as the refcounting support shared_ptr requires: we can call
> it tricky, but it is not a problem. Worst case, Noexcept has to
> implement it if it turns out that the built-in support on some platform
> is inefficient.

I remain unconvinced.

I'm still strongly of the opinion that if you want C++ exception like
semantics, turn on C++ exceptions support. The primary reason to use
Expected/Outcome/whatever is where it's better in every way to use those
semantics instead for some particular use case.

Niall

-- 
ned Productions Limited Consulting
http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk