[Python-ideas] Possible PEP 380 tweak
jh at improva.dk
Thu Oct 28 12:12:55 CEST 2010
On 2010-10-27 18:53, Jacob Holm wrote:
> 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
> 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.
Seems like I screwed up the semantics of the standard for-loop in that
version. Let me try again...
1) Add new exception StopCoIteration, inheriting from StandardError.
Change the regular StopIteration to inherit from the new exception
instead of directly from StandardError. This ensures that code that
catches StopCoIteration also catches StopIteration, which I think is
what we want.
The new exception is needed because "cocall func()" can never raise the
regular StopIteration (or any subclass thereof). This might actually be
an argument for using a different exception for returning a value from a
2) Allow __next__ on an object to be a cofunction. Add a __cocall__ to
the built-in next(ob) that tries to uses cocall to call ob.__next__.
def next__cocall__(ob, *args):
_next = type(ob).__next__
return cocall _next(ob)
2a) Optionally allow __iter__ on an object to be a cofunction. Add a
__cocall__ to the builtin iter.
def __init__(self, callable, sentinel):
self.callable = callable
self.sentinel = sentinel
v = cocall self.callable()
if v is sentinel:
ob, = args
callable, sentinel = args
return _func_iter(callable, sentinel)
_iter = type(ob).__iter__
return cocall _iter(ob)
3) Change the for-loop in a cofunction:
for val in iterable:
so it expands into:
_it = cocall iter(iterable)
val = cocall next(iterable)
which is exactly the normal expansion, but using cocall to call iter and
next, and catching StopCoIteration instead of StopIteration.
Since cocall falls back to using a regular call, this should work well
with all normal iterables.
3a) Alternatively define a new syntax for "coiterating", e.g.
cocall for val in iterable:
All this to make it possible to write a code like this:
cocall for val in ch:
cocall for val in range(10):
sched = scheduler()
ch = channel()
More information about the Python-ideas