We usually think about algorithms in a procedural manner – with loops,
branches and subroutines. Presenting an algorithm as an easily understandable
flow between its steps.
In the real world, where we need to reduce latency and forbid the blocking API
calls, these flows get broken. Due to the inversion of control (IoC) required
by the introduction of asynchronous APIs, the code becomes significantly more
complex. It ends up with being either a multi-agent system with lots of
messages passed around between agents, or an untangleable call-callback mess.
We will create an abstraction of the different types of asynchronous and
synchronous methods and structures that will allow us to write our programs in
a purely imperative manner, while leaving all the complexities of IoC to the
C++ compiler. The abstraction we will use is a relaxed variant of the
continuation monad. This approach will provide a similar set of features to
the await keyword proposed in N3564 while giving us more power, because
this abstraction will be usable not only for asynchronous execution, but will
be applicable to other monadic environments as well. And, unlike await, it can
be used with already released compilers.
We will be able to mimic all control structures provided by the host language
like serial execution, different loop types, branching and similar, along with
some more advanced ones like the different kinds of parallel execution or
automatic transaction management.
This approach eases the development in many cases like implementing the
networking clients or servers where we are not allowed to block the program
execution between sending a request and receiving a response; programs that
use a limited thread pool or thread-reusing with the producer-consumer design
pattern; programs that need to invoke an external process and handle its
output data in chunks or as a whole; programs that have more complex user (UI)
flows; distributed programs and similar.
It also eases up automatic testing, static analysis, and formal proving of
your programs, as we will demonstrate.
The work is heavily based on some of the new C++11 features like variadic
templates and lambdas, while also demonstrating some older template meta-
programming idioms like static introspection with SFINAE.