[Python-ideas] Cofunctions - an enhancement to yield-from

Jack Diederich jackdied at gmail.com
Fri Aug 6 02:15:05 CEST 2010


On Mon, Aug 2, 2010 at 12:39 PM, Guido van Rossum <guido at python.org> wrote:
> [snip]
>
> OTOH I do appreciate the desire to reduce the number of places where
> one has to sprinkle 'yield' over one's code, and I've had a number of
> situations recently where I had something that logically needed to be
> a coroutine (to match some API) but just happened not to need any
> yields, and inevitably my coding went something like (1) forget to put
> a yield in, (2) frantically debug, (3) slap forehead, (4) add "if 0:
> yield" to the function, (5) continue with another instance of this,
> (6) lose sleep over the best place to spell the dummy yield and where
> to put it. At the same time I don't want to have to mark all my
> coroutines with a decorator, like Monocle requires (though maybe I
> should).

We already use decorators to change interfaces so I am +1 on reusing
what people already know.  contextlib.contextmanager is shorthand for
"the following function is shorthand for a contextmanager"

from contextlib import contextmanager
@contextmanager
def myfunc(...): ...

So the generator equivalent would be

from somelib import generator
@generator
def myfunc(...): ...

Where generator is as simple as
def generator(func):
  def inner(*args, **opts):
    if False: yield
    return func(*args, **opts)
  return inner

But the bulk of Greg's proposal is to transform the called function in
one of two ways
In the original: to make this
    return func(*args, **opts)
equivalent to this
    yield from func.__cocall__(*args, **opts)  # func must be defined
with 'codef' or support __cocall__

Or in his second suggested form to make this
    cocall func(*args, **opts)
equivalent to this
    yield from func.__cocall__(*args, **opts) #  func must support __cocall__

I'm not sure if the "codef" keyword is included in the second form.

I'm -1 on the first proposal because it buries that the calling
function is a generator.  "yield from" (which it would be a synonym or
replacement for) lets you know the called function is a generator
without having to read the body of the called function.

I'm -1 on the 2nd form (explicit "cocall") because it is a synonym for
"yield from" and "yield from" fits my brain better because reads as
"this is yield-like but slightly different."

-Jack



More information about the Python-ideas mailing list