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

    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.


More information about the Python-list mailing list