[Python-ideas] Possible PEP 380 tweak (original) (raw)

Jacob Holm jh at improva.dk
Wed Oct 27 18:53:07 CEST 2010


On 2010-10-26 18:56, Guido van Rossum wrote:

Now, if I may temporarily go into wild-and-crazy mode (this is python-ideas after all :-), we could invent some ad-hoc syntax for this pattern, e.g.:

for value in yield: return IOW the special form: for in yield: would translate into: try: while True: = yield except GeneratorExit: pass If (and this is a big if) the while-True-yield-inside-try-except-GeneratorExit pattern somehow becomes popular we could reconsider this syntactic extension or some variant. (I have to add that the syntactic ice is a bit thin here, since "for in (yield)" already has a meaning, and a totally different one of course. A variant could be "for from yield" or some other abuse of keywords.

Hmm. This got me thinking. One thing I'd really like to see in python is something like the "channel" object from the go language (http://golang.org/).

Based on PEP 380 or Gregs new cofunctions PEP (or perhaps even without any of them) it is possible to write a trampoline-based implementation of a channel object with "send" and "next" methods that work as expected. One thing that is not possible (I think) is to make that object iterable. Your wild idea above gave me a similar wild idea of my own. An extension to the cofunctions PEP that would make that possible.

  1. Define a new "coiterator" protocol, consisting of a new special method conext, and a new StopCoIteration exception that the regular StopIteration inherits from. conext should be a generator that yields as many times as necessary, then either raises StopCoIteration or returns a result (possibly by raising a StopIteration with a value). Add a new built-in "conext" cofunction that looks for a conext method instead of a next method.

  2. Define a new "coiterable" protocol, consisting of a new special method coiter. coiter is a regular function and should return an object implementing the "coiterator" protocol. Add a new built-in "coiter" function that looks for a coiter method instead of an iter method. (We could also make this a cofunction but for now I don't see the point).

  3. Make sure that the for-loop in a cofunction:

    for val in coiterable:

    else:

expands as:

_it = coiter(coiterable) while True: try: val = cocall conext(_it) except StopCoIteration: break else:

Which is exactly the same as in a normal function, except for the use of "coiter" and "cocall conext" instead of "iter" and "next", and the use of StopCoIteration instead of StopIteration.

3a) Alternatively define a new syntax for "coiterating" that expands as in 3 and whose use is an alternative indicator that this is a cofunction.

All this to make it possible to write a code like this:

def consumer(ch): for val in ch: cocall print(val) # XXX need a cocall somewhere

def producer(ch): for val in range(10): cocall ch.send(val)

def main() sched = scheduler() ch = channel() sched.add(consumer(ch)) sched.add(producer(ch)) sched.run()

Thoughts?



More information about the Python-ideas mailing list