From 4be092d93e4acf6b3a1dfc6ba500ce3e72332582 Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Thu, 14 Dec 2000 14:53:02 +0000 Subject: [PATCH] Clarify rules for names defined in class scope. (Classes hide names was a bad label.) Add note about how to implement flat closures using an extra level of indirection. --- pep-0227.txt | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/pep-0227.txt b/pep-0227.txt index bf3087340..f5bdc1d03 100644 --- a/pep-0227.txt +++ b/pep-0227.txt @@ -56,11 +56,9 @@ Specification If a name is used within a code block, but it is not bound there and is not declared global, the use is treated as a reference to - the nearest enclosing function region. A region is visible from a - block is all enclosing blocks are introduced by function - defintions. (Note: If a region is contained within a class - definition, the name bindings that occur in the class block are - not visible to enclosed functions.) + the nearest enclosing function region. (Note: If a region is + contained within a class definition, the name bindings that occur + in the class block are not visible to enclosed functions.) A class definition is an executable statement that may uses and definitions of names. These references follow the normal rules @@ -111,19 +109,19 @@ Discussion name resolution rules are typical for statically scoped languages, with three primary exceptions: - - Class definitions hide names. + - Names in class scope are not accessible. - The global statement short-circuits the normal rules. - Variables are not declared. - Class definitions hide names. Names are resolved in the innermost - enclosing function scope. If a class defintion occurs in a chain - of nested scopes, the resolution process skips class definitions. - This rule prevents odd interactions between class attributes and - local variable access. If a name binding operation occurs in a - class defintion, it creates an attribute on the resulting class - object. To access this variable in a method, or in a function - nested within a method, an attribute reference must be used, - either via self or via the class name. + Names in class scope are not accessible. Names are resolved in + the innermost enclosing function scope. If a class defintion + occurs in a chain of nested scopes, the resolution process skips + class definitions. This rule prevents odd interactions between + class attributes and local variable access. If a name binding + operation occurs in a class defintion, it creates an attribute on + the resulting class object. To access this variable in a method, + or in a function nested within a method, an attribute reference + must be used, either via self or via the class name. An alternative would have been to allow name binding in class scope to behave exactly like name binding in function scope. This @@ -295,17 +293,17 @@ Implementation code and the environment in which to resolve free variables. There are a variety of implementation alternatives for closures. - One possibility is to use a static link from a nested function to - its enclosing environment. This implementation requires several - links to be followed if there is more than one level of nesting - and keeps many garbage objects alive longer than necessary. + Two typical ones are nested closures and flat closures. Nested + closures use a static link from a nested function to its enclosing + environment. This implementation requires several links to be + followed if there is more than one level of nesting and keeps many + garbage objects alive longer than necessary. - One fairly simple implementation approach would be to implement - the default argument hack currently used for lambda support. Each - function object would have a func_env slot that holds a tuple of - free variable bindings. The code inside the function would use - LOAD_ENV to access these bindings rather than the typical - LOAD_FAST. + Flat closures are roughly similar to the default argument hack + currently used for lambda support. Each function object would + have a func_env slot that holds a tuple of free variable bindings. + The code inside the function would use LOAD_ENV to access these + bindings rather than the typical LOAD_FAST. The problem with this approach is that rebindings are not visible to the nested function. Consider the following example: @@ -329,6 +327,10 @@ Implementation definition time. This is the default argument hack, but not actual name resolution based on statically nested scopes. + To support shared visibility of updates, it will be necessary to + have a tuple of cells that contain references to variables. The + extra level of indirection should allow updates to be shared. + It is not clear whether the current 1-pass Python compiler can determine which references are to globals and which are references to enclosing scopes. It may be possible to make minimal changes