title: Coroutine usages for asynchronous programming in C++
body: <p>I decided to immerse into C++ coroutines, have read some articles and watched a lot of videos. It is said that coroutines are useful for asynchronous programming. As an example it is usual demonstrated similar examples.
  Let's look to one of them: <a href="https://www.youtube.com/watch?v=ZTqHjjm86Bw&amp;t=100s" rel="nofollow noreferrer">James McNellis "Introduction to C++ Coroutines" from CppCon2016 (Timing 1:40 - 6:00)</a>.</p>
  
  <p>Imagine that we want to establish TCP connection and get data from TCP connection:</p>
  
  <pre><code>int64_t tcp_reader(int64_t total) {
    std::array&lt;char, 4096&gt; buffer;
    tcp::connection the_connection = tcp::connect("127.0.0.1", 1337);
    int64_t remaining = total;
    for (;;) {
      int64_t bytes_read = the_connection.read(buffer.data(), buffer.size()).get();
      remaining -= bytes_read;
      if (remaining &lt;= 0 || bytes_read == 0) { return remaining); }
    }
  }
  </code></pre>
  
  <p>It is not asynchronous, let's imagine that connect() and read() functions already asynchronous(returns std::future) and re-write the function in asynchronous way(too much typing, inserted a picture instead):
  <a href="https://i.stack.imgur.com/fewoH.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fewoH.png" alt="Snapshot of https://www.youtube.com/watch?v=ZTqHjjm86Bw&amp;t=1695s"></a></p>
  
  <p>Hmmmmm. Looks crazy, let's rewrite it with coroutines:</p>
  
  <pre><code>// std::future instead of just int
  std::future&lt;int64_t&gt; tcp_reader(int64_t total) {
    std::array&lt;char, 4096&gt; buffer;
    // tcp::connect returns std::future. Added co_await
    tcp::connection the_connection = co_await tcp::connect("127.0.0.1", 1337);
    int64_t remaining = total;
    for (;;) {
      // tcp::connect::read returns std::future. Added co_await
      int64_t bytes_read = co_await the_connection.read(buffer.data(), buffer.size()).get();
      remaining -= bytes_read;
      if (remaining &lt;= 0 || bytes_read == 0) { return remaining); }
    }
  }
  </code></pre>
  
  <p>I do not understand why we complicate it so much. I would just rewrite initial code like this:</p>
  
  <pre><code>int64_t tcp_reader(int64_t total) {
    std::array&lt;char, 4096&gt; buffer;
    // tcp::connect returns std::future. Add get();
    tcp::connection the_connection = tcp::connect("127.0.0.1", 1337).get();
    int64_t remaining = total;
    for (;;) {
      // tcp::connect::read returns std::future. Add get();
      int64_t bytes_read = the_connection.read(buffer.data(), buffer.size()).get();
      remaining -= bytes_read;
      if (remaining &lt;= 0 || bytes_read == 0) { return remaining); }
    }
  }
  std::future&lt;int64_t&gt; async_tcp_reader(int64_t total) {
    return std::async([total]{ tcp_reader(total); });
  }
  </code></pre>
  
  <p>Simple and straightforward, isn't it?</p>
  
  <p>I also looked to await/async examples in other languages(Python/JS), there are similar usages.</p>
  
  <p><strong>Is there are any advantages of using coroutines, comparably to my code in this example?</strong></p>
  
  <p><strong>How coroutines can improve my asynchronous code? If you know, please, provide some examples that can illustrate the power of coroutines in async programming</strong></p>