Update to PEP 227 (static scoping)

Russell E. Owen owen at astrono.junkwashington.emu
Thu Feb 22 14:30:44 EST 2001


In article <mailman.982783412.29104.python-list at python.org>, 
jeremy at alum.mit.edu wrote:

(much of generally excellent description of PEP 227 omitted)

>    A class definition is an executable statement that may uses and
>    definitions of names.

Might you rephrase this? I hope there is a typo here.

>Discussion
>...
>    Variables are not declared.  If a name binding operation occurs
>    anywhere in a function, then that name is treated as local to the
>    function and all references refer to the local binding.  If a
>    reference occurs before the name is bound, a NameError is raised.
>    The only kind of declaration is the global statement, which allows
>    programs to be written using mutable global variables.  As a
>    consequence, it is not possible to rebind a name defined in an
>    enclosing scope.  An assignment operation can only bind a name in
>    the current scope or in the global scope.  The lack of
>    declarations and the inability to rebind names in enclosing scopes
>    are unusual for lexically scoped languages; there is typically a
>    mechanism to create name bindings (e.g. lambda and let in Scheme)
>    and a mechanism to change the bindings (set! in Scheme).

I confess to being nervous about this proposed change. Static scoping 
does add some very nice functionality, but it seems to come at a 
significant cost in
- complexity (the new rules have some tricky exceptions)
- safety (Tim's example is a good one; also typos can do more damage)

I realize this has probably been discussed at length by people 
intimately connected with the language, so I'm on thin ice here, but 
I'll speak up anyway.

Firstly, I am wondering if we might not be able to obtain a most of the 
gains of this proposal with less of the negative aspects by scaling it 
back?

It seems that the most important driver for these new rules is lambda 
functions. It also helps in other areas, but somebody pointed out that 
folks where generally content with the old scoping rules until lambda 
functions were introduced. So...perhaps one could improve the syntax for 
lambda functions, instead of messing with scoping? Here is one 
possibility:

lambda list-of-args : list-of-non-local-variables : code

This basically does the same as the default argument trick. It would be 
nice if it was an error to try to refer to non-local variables as 
arguments when calling lambda, but this is by no means necessary.



If the more general solution of static scoping is desired (and it does 
have some advantages, of course), then here are some further thoughts:

How about requiring an explicit statement that "this variable is 
non-local"? This is reminiscent of the existing "global" keyword. This 
has several advantages, to my mind:
- It works equally well in functions and in class methods. Hence classes 
don't need to be special-cased in the new rules.
- The common and most-desirable cases (all variables are local or were 
in the argument list) is the default; if you want to access non-local 
variables (which is less common and potentially more dangerous) you have 
to be explicit about it.

I think a keyword is best, as it matches the existing "global" keyword, 
providing nice regularity.

The one problem I see with a keyword is lambda functions (which I don't 
think could use it). For that, perhaps again one could adopt special 
notation, such as listed above, for specifying the non-local variables 
it will use.



If it is not deemed desirable to require declaring non-local variables, 
then I do have a final plea: some *optional* means of explicitly 
declaring a variable as local.

Such notation was not needed with the old scoping rules, but I think 
it'll be very useful for writing safe code with the new rules. Good 
coding practice (especially in large projects) would suggest using it 
for all programs -- to avoid typos causing mysterious bugs.

Optional explicit declaration also enables the ability to warn of the 
use of non-declared variables. Something that can be very nice for large 
projects -- since it catches typos.


-- Russell



More information about the Python-list mailing list