On Mon, May 25, 2015 at 10:37 AM, Niall Douglas
Dear list,
Hi Niall [snip]
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.
So, the future/promise pair can be optimized out if the work can be completed synchronously (i.e. immediately or at get time). But then, why use a future at all? What is the use case you are trying to optimize for? do you have an example? I have an use case for very light weight futures as I have been experimenting with cilk-style work stealing. In the fast (non stolen) clone you want the futures to have zero overhead (other than the steal check) as the computation is strictly synchronous. I do not think a generic future would be appropriate. Re allocation, you know my views :). [...]
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 agree that generally as a result holder you want either
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.
I believe that trying to design a future that can fulfill everybody's requirements is a lost cause. The c++ way is to define concepts and algorithms that work on concepts. The types we want to generalize are std::future, expected, possibly optional and all the other futures that have been cropping up in the meantime. The algorithms are of course those required for composition: then, when_all, when_any plus probably get and wait. We could just take a page from Haskell and call the concept Monad, but maybe we want something more specific, like Result. Then, in addition to the algorithms themselves, there is certainly space in boost for a library for helping build custom futures, a-la boost.iterator. -- gpd