title: Python chained `yield form`
body: <p>I was reading through this <a href="https://snarky.ca/how-the-heck-does-async-await-work-in-python-3-5/" rel="nofollow noreferrer">article</a> about async and await in python, and saw this sample code:</p>
  
  <pre><code>def bottom():
      # Returning the yield lets the value that goes up the call stack to come right back
      # down.
      return (yield 42)
  
  def middle():
      return (yield from bottom())
  
  def top():
      return (yield from middle())
  
  # Get the generator.
  gen = top()
  value = next(gen)
  print(value)  # Prints '42'.
  try:
      value = gen.send(value * 2)
  except StopIteration as exc:
      value = exc.value
  print(value)  # Prints '84'.
  </code></pre>
  
  <p>I can understand the chaining generators to return <code>42</code>, but I can't seem to get my head around <code>gen.send(value * 2)</code> and get 84 back. I would have thought initial <code>next(gen)</code> would have already exhausted the generator as following experiment?</p>
  
  <pre><code>def bottom():
      # Returning the yield lets the value that goes up the call stack to come right back
      # down.
      return (yield 42)
  
  def middle():
      return (yield from bottom())
  
  def top():
      return (yield from middle())
  
  # Get the generator.
  gen = top()
  value = next(gen)
  print(value)  # Prints '42'.
  
  value = next(gen)
  print(value)
  
  Traceback (most recent call last):
    File "a.py", line 16, in &lt;module&gt;
      value = next(gen)
  StopIteration
  </code></pre>
  
  <p>Could someone please explain?</p>
  
  <p>PS: Not the most well thought out title, someone please help fix it...</p>