Update to PEP 227 (static scoping)
Russell E. Owen
owen at astrono.junkwashington.emu
Thu Feb 22 20:30:44 CET 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.
> 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
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
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.
More information about the Python-list