Closed sean-parent closed 1 year ago
I reimplemented the reduce mechanism as a (manually written) coroutine and added reduce as a feature to async.
The executor is now set correctly on the reduced future so continuations will execute where the wrapping future would have executed.
Reduce is now an independent algorithm but not exposed as the intention is to always auto-reduce and the mechanism may get pushed lower in the future.
The key insight was to rethink the reduction as:
auto reduce(E e, future<future<R>>&& r) -> future<R> { return async(e, [](future<future<R>>&& r) -> task<R> { co_return co_await co_await move(r); }); }
The above may be implementable directly with coroutines in the future. For now, I implemented it with a manual coroutine.
I like the solution. It is much better than the one that I did some years ago!
I reimplemented the reduce mechanism as a (manually written) coroutine and added reduce as a feature to async.
The executor is now set correctly on the reduced future so continuations will execute where the wrapping future would have executed.
Reduce is now an independent algorithm but not exposed as the intention is to always auto-reduce and the mechanism may get pushed lower in the future.
The key insight was to rethink the reduction as:
The above may be implementable directly with coroutines in the future. For now, I implemented it with a manual coroutine.