[Python-Dev] Explicit Lexical Scoping (pre-PEP?)

Phillip J. Eby pje at telecommunity.com
Wed Jul 5 08:26:25 CEST 2006


At 05:49 AM 7/5/2006 +0200, Guido van Rossum wrote:
>>* Alternate spelling of outer names when binding (e.g. ".x = whatever" to
>>bind an outer x)
>
>We looked at and rejected "globals.x = whatever". I think the same
>reasoning applies here.

I thought the 'globals.x' proposal required that 'x' always be accessed 
using 'globals', even if it wasn't being rebound.  I don't see a problem 
with requiring '.x' to be used for both reading and writing of outer-scope 
names; it just shouldn't be required for an outer-scope name that you don't 
rebind in the current scope.  That symmetry requirement can't be 
implemented with the 'globals.x' approach unless 'globals' is treated 
specially by the compiler.

Using the classic nonsense example:

     def counter(num):
         def inc():
             .num += 1
             return .num
         return inc

If inc() only needed to *read* num, it could just use 'num' without the 
'.', and be nicely backward compatible with today's Python.

(Note: It should be illegal to use both '.num' and 'num' in the same scope, 
whether writing or reading the value, to prevent readers from becoming 
confused about what variable you mean.  It should also be required that the 
compiler can see a definition of 'num' in an outer scope if you use the 
'.num' syntax, so that misspelling a name doesn't create a global variable.)

I personally think this approach could be the overall least-intrusive 
solution as far as syntax goes.  It also allows for dropping the 'global' 
keyword in 3.x, and it has a nice EIBTI feel to it, as it allows you to 
highlight closure variables in an inner function by using the '.'.  It's 
often not obvious when an inner function (such as a decorator returned by a 
decorator factory) is using variables that were defined in the outer scope; 
the leading '.' would make them stand out, and so could be considered the 
recommended code style when referring to outer variables.

In addition, there's a nice symmetry between nested functions and top-level 
functions, e.g. in this global version of the counter example:

     num = 0
     def inc():
         .num += 1
         return .num

The principle downside taht I see is that it uses semi-random punctuation 
in place of keywords.  OTOH, we are already using more-or-less this syntax 
for relative imports, so reusing it to mean "relative variables" seems to 
at least avoid creating any entirely new principles.  :)

Anyway, I won't argue this one further; I just wanted to make sure it had 
been considered, as I'm not sure that you were reading the thread where it 
was first brought up (possibly as long as a few months ago).



More information about the Python-Dev mailing list