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 08:44:36

On 05/25/2015 12:37 PM, Niall Douglas wrote:
> Dear list,
> As AFIO looks likely to be finally getting a community review soon,
> I've made a start on a final non-allocating constexpr-collapsing next
> generation future-promise such that the AFIO you review is "API
> final". You may remember my experimentations on those from:
> 8339.html.
> Essentially the win is that future-promise generates no code at all
> on recent C++ 11 compilers unless it has to [1], and when it does it
> generates an optimally minimal set with no memory allocation unless T
> does so. This should make these future-promises several orders of
> magnitude faster than the current ones in the C++ standard and solve
> their scalability problems for use with things like ASIO. They also
> have major wins for resumable functions which currently always
> construct a promise every resumable function entry - these next gen
> future-promises should completely vanish if the resumable function
> never suspends, saving a few hundred cycles each call.
> Anyway, my earlier experiments were all very promising, but they all
> had one big problem: the effect on compile time. My final design is
> therefore ridiculously simple: a future<T> can return only these
> options:
> * A T.
> * An error_code (i.e. non-type erased error, optimally lightweight)
> * An exception_ptr (i.e. type erased exception type, allocates
> memory, you should avoid this if you want performance)

I believe error_code is unneeded. Exceptions are expected to be slow.
If you want another type of variant return, let the user encapsulate it
in T (could be optional<T>, or expected<T, E>, or whatever).

> In other words, it's a fixed function monad where the expected return
> is T, and the unexpected return can be either exception_ptr or
> error_code. The next gen future provides Haskell type monadic
> operations similar to Boost.Thread + Boost.Expected, and thanks to
> the constexpr collapse this:
> future<int> test() {
> future<int> f(5);
> return f;
> }
> test().get();
> ... turns into a "mov $5, %eax", so future<T> is now also a
> lightweight monadic return transport capable of being directly
> constructed.

Can you post the code? I'd be very interested in comparing it with
seastar's non-allocating futures.

> In case you might want to know why a monadic return transport might
> be so useful as to be a whole new design idiom for C++ 11, try
> reading
> tronglyconsiderusingconstexprsemanticwrappertransporttypestoreturnstat
> esfromfunctions.
> However, future<T> doesn't seem named very "monadic", so I am
> inclined to turn future<T> into a subclass of a type better named.
> Options are:
> * result<T>
> * maybe<T>
expected<T, E> was proposed (where E = std::exception_ptr).

> Or anything else you guys can think of? future<T> is then a very
> simple subclass of the monadic implementation type, and is simply
> some type sugar for promise<T> to use to construct a future<T>.
> Let the bike shedding begin! And my thanks in advance.
> Niall
> [1]: Compiler optimiser bugs notwithstanding. Currently only very
> recent GCCs get this pattern right. clang isn't bad and spills a
> dozen or so completely unnecessary opcodes, and I'll follow up with
> Chandler with some bug reports to get clang fixed. Poor old MSVC
> spits out about 3000 lines of assembler, it can't do constexpr
> folding at all yet.

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