Why read-only nested scopes?
Jeremy Hylton
jeremy at alum.mit.edu
Thu Sep 5 15:16:33 EDT 2002
David Eppstein <eppstein at ics.uci.edu> wrote in message news:<eppstein-56D20B.14244204092002 at news.service.uci.edu>...
> In article <m7ncnugbkm0qghf66qcub6e37b64fesdkq at 4ax.com>,
> Gonçalo Rodrigues <op73418 at mail.telepac.pt> wrote:
>
> > Anyway, I've been directed to PEP 227, cheerfully obeyed, and from what
> > I have understood having read-only nested scopes was more of a design
> > decision than something else. And while I can live happily with the
> > decision (some would even say happier) there is something about the "You
> > can look at it but not touch it" attitude that I dislike ;-)
>
> I'm sure there were good reasons for this decision, but it leads to ugly
> workarounds like making each nonlocal variable into a list and assigning
> to x[0] instead of x...
I agree with you in principle. I think that nested scopes would be
cleaner if they allowed rebinding names in enclosing scopes. But it's
not a limitation that has ever caused me grief. There are a variety
of workarounds. The use of a list to represent a mutable variable is
one, but replacing the nested function with a class works, too.
Here's what I had to say in PEP 227 about the current state of
affairs:
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.
Jeremy
More information about the Python-list
mailing list