[Prev][Next][Index][Thread]
Re: Closures
-
To: info-dylan@ai.mit.edu
-
Subject: Re: Closures
-
From: Samuele Pedroni <pedroni@inf.ethz.ch>
-
Date: Tue, 14 Aug 2001 03:45:02 -0400 (EDT)
-
Organization: Swiss Federal Institute of Technology (ETHZ)
-
References: <200108131526.LAA06274@life.ai.mit.edu>
-
Xref: traf.lcs.mit.edu comp.lang.dylan:13589
Jeff Dalton wrote:
> The Python "idiomatic way to get the same" below does not seem to
> close over local variables at all.
>
> > > > There is simply another idiomatic way to get the same:
> > > >
> > > > class counter:
> > > > def __init__(self):
> > > > self.n = 0
> > > > def __call__(self):
> > > > self.n = self.n + 1
> > > > return self.n
> > > >
> > > > c=counter()
> > > > print c()
> > > > print c()
It closes but still you can't assign:
def make_counter_with_incr(inc):
class ctr:
def __init__(self):
self.n = 0
def __call__(self):
self.n = self.n + inc
return self.n
return ctr
c=make_counter_with_incr(4)
print c() # 4
print c() # 8
>
> The interesting question is why: why have Dylan and modern Lisps
> gone this way when virtually no one else has? Why were Lisp and Dylan
> not satisfied with some kind of "approximate closure" when so many
> others were? Java came close but didn't take the final step of supporting
> assignment. In functional languages, the issue doesn't arise (no
> assignment); and in ML they avoid it by using explicit ref objects.
Here the rationale for Python, mostly a GvR (aka Python BDFL) point:
> There are technical issues that make it difficult to support
> rebinding of names in enclosing scopes, but the primary reason
> that it is not allowed in the current proposal is that Guido is
> opposed to it. His motivation: it is difficult to support,
> because it would require a new mechanism that would allow the
> programmer to specify that an assignment in a block is supposed to
> rebind the name in an enclosing block; presumably a keyword or
> special syntax (x := 3) would make this possible. Given that this
> would encourage the use of local variables to hold state that is
> better stored in a class instance, it's not worth adding new
> syntax to make this possible (in Guido's opinion).
>
> The proposed rules allow programmers to achieve the effect of
> rebinding, albeit awkwardly. The name that will be effectively
> rebound by enclosed functions is bound to a container object. In
> place of assignment, the program uses modification of the
> container to achieve the desired effect:
>
> def bank_account(initial_balance):
> balance = [initial_balance]
> def deposit(amount):
> balance[0] = balance[0] + amount
> return balance
> def withdraw(amount):
> balance[0] = balance[0] - amount
> return balance
> return deposit, withdraw
>
> Support for rebinding in nested scopes would make this code
> clearer. A class that defines deposit() and withdraw() methods
> and the balance as an instance variable would be clearer still.
> Since classes seem to achieve the same effect in a more
> straightforward manner, they are preferred.
>
>
A special syntax was needed and the effort was deemed counterproductive.
(PEP 227, http://python.sourceforge.net/peps/pep-0227.html )
>
> (By the way, does Perl have lexical scoping?)
Yes
That's all folks.
PS: GvR is known to have said something along the line of: the mind of the
average Python programmer is simpler than that of average Lisp programmer.
I think both groups get an appropriate set of tools.
What I miss sometimes in Python are (dylan/Lisp like) macros, but that would
be a major exercise in language design and would clash with the
everything-happens-cleanly-at-runtime semantics of Python. GvR probably will
never let such a beast sneak in the language.