[Python-Dev] closure semantics
Samuele Pedroni
pedronis at bluewin.ch
Fri Oct 24 09:53:57 EDT 2003
At 16:22 23.10.2003 -0700, Guido van Rossum wrote:
> > > def tee(iterable):
> > > "Return two independent iterators from a single iterable"
> > > data = {}
> > > cnt = 0
> > > def gen(next):
> > > global* cnt
> > > dpop = data.pop
> > > for i in count():
> > > if i == cnt:
> > > item = data[i] = next()
> > > cnt += 1
> > > else:
> > > item = dpop(i)
> > > yield item
> > > next = iter(iterable).next
> > > return (gen(next), gen(next))
> > >
> > >which is IMO more readable.
> >
> > it's a subtle piece of code. I wouldn't mind a more structured syntax with
> > both the outer function declaring that is ok for some inner function to
> > rebind some of its locals, and the inner function declaring that a
> local is
> > coming from an outer scope:
> >
> > def tee(iterable):
> > "Return two independent iterators from a single iterable"
> > data = {}
> >
> > # cnt = 0 here would be ok
> >
> > share cnt = 0: # the assignment is opt,
> > # inner functions in the suite can rebind cnt
> > def gen(next):
> > use cnt # OR outer cnt
> > dpop = data.pop
> > for i in count():
> > if i == cnt:
> > item = data[i] = next()
> > cnt += 1
> > else:
> > item = dpop(i)
> > yield item
> >
> > # cnt = 0 here would be ok
> >
> > next = iter(iterable).next
> > return (gen(next), gen(next))
> >
> > yes it's heavy and unpythonic, but it makes very clear that something
> > special is going on with cnt.
>
>Might as well declare a class then. :-)
well, no, it's probably that I expect rebindable closed-over vars to be
introduced
but some kind of structured construct instead of the usual Python freeform.
I think
for this kind of situation I miss the Lisp-y 'let'.
def counter(starval):
share cnt = startval:
def inc(i):
use cnt
cnt += i
return cnt
def dec(i)
use cnt
cnt -= i
return cnt
return inc,dec
vs.
def counter(starval):
cnt = startval
def inc(i):
global cnt in counter
cnt += i
return cnt
def dec(i)
global cnt in counter
cnt -= i
return cnt
return inc,dec
vs.
def counter(starval):
class Counter:
def __init__(self,startval):
self.cnt = startval
def inc(self,i):
self.cnt += i
return self.cnt
def dec(self,i):
self.cnt += i
return self.cnt
newcounter = Counter(startval)
return newcounter.inc,newcounter.dec
vs.
(defun counter (startval)
(let ((cnt startval))
(flet ((inc (i)
(incf cnt i))
(dec (i)
(decf cnt i)))
(values #'inc #'dec))))
<wink>
More information about the Python-Dev
mailing list