== Coroutines Coroutines are resumable functions. Resumable means that a function can suspend, i.e. pass the control back to the caller multiple times. A regular function yields control back to the caller with the `return` function, where it also returns the value. A coroutine on the other hand might yield control to the caller and get resumed multiple times. A coroutine has three control keywords akin to co_return (of which only `co_return` has to be supported). - `co_return` - `co_yield` - `co_await` === `co_return` This is similar to `return`, but marks the function as a coroutine. === `co_await` The `co_await` expression suspends for an <>, i.e. stops execution until the `awaitable` resumes it. E.g.: [source,cpp] ---- cobalt::promise delay(std::chrono::milliseconds); cobalt::task example() { co_await delay(std::chrono::milliseconds(50)); } ---- A `co_await` expression can yield a value, depending on what it is awaiting. [source,cpp] ---- cobalt::promise read_some(); cobalt::task example() { std::string res = co_await read_some(); } ---- NOTE: In `cobalt` most coroutine primitives are also <>. === `co_yield` The `co_yield` expression is similar to the `co_await`, but it yields control to the caller and carries a value. For example: [source,cpp] ---- cobalt::generator iota(int max) { int i = 0; while (i < max) co_yield i++; co_return i; } ---- A `co_yield` expression can also produce a value, which allows the user of yielding coroutine to push values into it. [source,cpp] ---- cobalt::generator iota() { int i = 0; bool more = false; do { more = co_yield i++; } while(more); co_return -1; } ---- .Stackless **** C++ coroutine are stack-less, which means they only allocate their own function frame. See <> for more details. ****