[Python-Dev] PEP 342: simple example, closure alternative
Ian Bicking
ianb at colorstudy.com
Thu Aug 25 21:10:43 CEST 2005
I was trying to translate a pattern that uses closures in a language
like Scheme (where closed values can be written to) to generators using
PEP 342, but I'm not clear exactly how it works; the examples in the PEP
have different motivations. Since I can't actually run these examples,
perhaps someone could confirm or debug these:
A closure based accumulator (using Scheme):
(define (accum n)
(lambda (incr)
(set! n (+ n incr))
n))
(define s (accum 0))
(s 1) ; -> 1 == 0+1
(s 5) ; -> 6 == 1+5
So I thought the generator version might look like:
def accum(n):
while 1:
incr = (yield n) or 0
n += incr
>>> s = accum(0)
>>> s.next()
>>> s.send(1)
0
>>> s.send(5)
1
>>> s.send(1)
6
Is the order of the output correct? Is there a better way to write
accum, that makes it feel more like the closure-based version?
Is this for loop correct?
>>> s = accum(0)
>>> for i in s:
... if i >= 10: break
... print i,
... assert s.send(2) == i
0 2 4 6 8
Hmm... maybe this would make it feel more closure-like:
def closure_like(func):
def replacement(*args, **kw):
return ClosureLike(func(*args, **kw))
return replacement
class ClosureLike(object):
def __init__(self, iterator):
self.iterator = iterator
# I think this initial .next() is required, but I'm
# very confused on this point:
assert self.iterator.next() is None
def __call__(self, input):
assert self.iterator.send(input) is None
return self.iterator.next()
@closure_like
def accum(n):
while 1:
# yields should always be in pairs, the first yield is input
# and the second yield is output.
incr = (yield) # this line is equivalent to (lambda (incr)...
n += incr # equivalent to (set! ...)
yield n # equivalent to n; this yield always returns None
>>> s = accum(0)
>>> s(1)
1
>>> s(5)
6
Everything before the first (yield) is equivalent to the closed values
between "(define (accum n)" and "(lambda" (for this example there's
nothing there; I guess a more interesting example would have closed
variables that were written to that were not function parameters).
--
Ian Bicking / ianb at colorstudy.com / http://blog.ianbicking.org
More information about the Python-Dev
mailing list