<div dir="ltr"><div class="gmail_extra">On 24 February 2015 at 21:00, Steven D'Aprano <span dir="ltr"><<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If I have a function which expects a *primed* coroutine, and you provide<br>
an unprimed one, we get an obvious error:<br>
<br>
py> def handle_primed(co):<br>
...     for i in (1, 3, 5):<br>
...             y = co.send(i)<br>
...     return y<br>
...<br>
py> handle_primed(runningsum())  # Oops, unprimed!<br>
Traceback (most recent call last):<br>
  File "<stdin>", line 1, in <module><br>
  File "<stdin>", line 3, in handle_primed<br>
TypeError: can't send non-None value to a just-started generator<br></blockquote><div><br><div class="gmail_default" style="font-family:monospace">​Why would you ever want to use that function "unprimed", though? Writing "next(rs)" or "rs.send(None)" just seems like busywork​ to me; it's not something I'd write if I were writing pseudocode, so it's something I wish python didn't force me to write in order to use that language feature...<br></div><br><div class="gmail_default" style="font-family:monospace">​But... you could just use a decorator to make that go away, I think? As in having a decorator along the lines of:<br><br></div><div class="gmail_default" style="font-family:monospace">  def primed_coroutine(f):<br></div><div class="gmail_default" style="font-family:monospace">      @wraps(f)<br></div><div class="gmail_default" style="font-family:monospace">      def fprime(*args, **kwargs):<br></div><div class="gmail_default" style="font-family:monospace">          co = f(*args, **kwargs)<br></div><div class="gmail_default" style="font-family:monospace">          next(co)<br></div><div class="gmail_default" style="font-family:monospace">          return co<br></div><div class="gmail_default" style="font-family:monospace">      return fprime<br></div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">so that you could write and use a coroutine just by having:<br></div><div class="gmail_default" style="font-family:monospace"><br></div><div class="gmail_default" style="font-family:monospace">  @primed_coroutine<br></div><div class="gmail_default" style="font-family:monospace">  def runningsum():<br></div><div class="gmail_default" style="font-family:monospace">      total = 0<br></div><div class="gmail_default" style="font-family:monospace">      while True:<br></div><div class="gmail_default" style="font-family:monospace">          total += (yield total)​</div><br><div class="gmail_default" style="font-family:monospace">​  handle_primed(runningsum())</div></div><br><div class="gmail_default" style="font-family:monospace">​At least, now that I've thought of it, that's how I plan to write any generator-based coroutines in future...<br><br></div><div class="gmail_default" style="font-family:monospace">Cheers,<br></div><div class="gmail_default" style="font-family:monospace">aj​</div></div></div></div>