|
Boost : |
Subject: [boost] [next gen future-promise] What to call the monadic return type?
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-05-25 05:37:26
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:
http://boost.2283326.n4.nabble.com/Non-allocating-future-promise-td466
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)
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.
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
https://svn.boost.org/trac/boost/wiki/BestPracticeHandbook#a8.DESIGN:S
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>
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.
-- 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