[Python-ideas] A send() built-in function to drive coroutines

Steven D'Aprano steve at pearwood.info
Tue Feb 24 16:54:17 CET 2015


On Tue, Feb 24, 2015 at 10:56:49PM +1000, Anthony Towns wrote:
> On 24 February 2015 at 21:00, Steven D'Aprano <steve at pearwood.info> wrote:
> 
> > If I have a function which expects a *primed* coroutine, and you provide
> > an unprimed one, we get an obvious error:
[...]
> ​Why would you ever want to use that function "unprimed", though? 

I wouldn't. If I wrote a function that expected a coroutine as argument, 
I would always expect that the caller would prime the coroutine before 
sending it to me. If they forget, they will get an exception. But 
Luciano seems to wish to accept both primed and unprimed coroutines, so 
I'm just following his requirements as I understand them.

[...]
> ​But... you could just use a decorator to make that go away, I think? As in
> having a decorator along the lines of:
> 
>   def primed_coroutine(f):
>       @wraps(f)
>       def fprime(*args, **kwargs):
>           co = f(*args, **kwargs)
>           next(co)
>           return co
>       return fprime

Indeed. That is exactly what I do in my code, so all my coroutines are 
primed as soon as they are created and I never have to worry about 
them being unprimed. My code is virtually the same as yours, except I 
call the decorator "coroutine".

@coroutine
def running_sum():
    ...


makes it clear that running_sum is a coroutine, not a regular function 
or generator.

Although the decorator is quite simple, I think that *every* user of 
coroutines should be using it. Are there any use-cases for unprimed 
coroutines? Perhaps this decorator should become a built-in, or at least 
in functools?



-- 
Steve


More information about the Python-ideas mailing list