Boost logo

Boost :

Subject: Re: [boost] [next gen future-promise] What to call the monadic return type?
From: Avi Kivity (avi_at_[hidden])
Date: 2015-05-25 14:24:21

On 05/25/2015 07:37 PM, Niall Douglas wrote:
> On 25 May 2015 at 18:33, Avi Kivity wrote:
>>> In particular, error_code is fast, and unexpected returns are not
>>> exceptional and must be as fast as expected returns.
>> As I mentioned, in this case the user can use expected<> or similar
>> themselves.
> As I mentioned, expected<> is too hard on compile times for large
> code bases. It's also way overkill for what 98% of use cases need.
>> Otherwise, what's the type of error_code? There could be an
>> infinite amount of error_code types to choose from (starting with simple
>> 'enum class'es and continuing with error codes that include more
>> information about the error (nonscalar objects).
> It's std::error_code. Same as ASIO uses. If being compiled as part of
> Boost, I expect boost::error_code and boost::exception_ptr will work
> too as additional variant options.
>>> Also, any monadic transport would default construct to an unexpected
>>> state of a null error_code in fact, which is constexpr. This lets one
>>> work around a number of exception safety irritations where move
>>> constructor of T is not noexcept more easily.
>> I'm not sure how the default constructor of future<> and the move
>> constructor of T are related.
> Well, let's assume we're really talking about a maybe<T>, and
> future<T> subclasses maybe<T> with additional thread safety stuff.
> In this situation a maybe<T> doesn't need a default constructor, but
> because it's a fixed variant we always know that error_code is
> available, and error_code (a) doesn't allocate memory and (b) is STL
> container friendly, so it seems sensible to make maybe<T> also STL
> container friendly by letting it default to error_code.
> The problem, as with the WG21 proposed variant, is getting move
> assignment to not undefine behaviour the existing contents if the
> throwing move constructor throws. Boost Variant's copy constructor
> dynamically allocates a temporary copy of itself internally to give
> that strong guarantee - this is unacceptable overhead for mine. So I
> need some well defined state to default to if during move assignment
> my move constructor throws after I have destructed my current state.
> Defaulting to an error_code saying the move constructor threw is a
> reasonable well defined outcome.
>> I'm not even sure why future<> would require a default constructor.
>> Seastar's doesn't have one.
> My future promise is as close to a strict superset of the Concurrency
> TS as is possible. It should be drop in replaceable in 99% of use
> cases, with the only point of failure being if you are trying to use
> allocators with your futures.
> My future promise is also intended to enter the Boost.Thread rewrite
> as the next gen future promise, if it proves popular.
>>>>> ... turns into a "mov $5, %eax", so future<T> is now also a
>>>>> lightweight monadic return transport capable of being directly
>>>>> constructed.
>> I'm looking forward to it! I've been bitten by the same compile time
>> explosion problems and I'm curious to see how you solved them.
> With a great deal of concentrated study of compiler diagnostics and
> trial and error!
> Once they are working and they are being unit tested per commit, I'll
> get a CI failure every time I break it. That should make things
> enormously easier going. Lots of machinery and scripting to come
> before that though.
> I've got everything working except the sequence:
> promise<int> p;
> p.set_value(5);
> return p.get_future().get();
> This should reduce to a mov $5, %eax, but currently does not for an
> unknown reason. I'm just about to go experiment and see why.

I managed to get very close to this by sprinking always_inline
attributes, mostly at destructors.

As soon as the compiler makes a bad inlining decision, it loses track of
the values it propagated and basically has to undo all optimization.

It's still not perfect (one extra instruction) though.

(using gcc 5).

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