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.
This commit is contained in:
Jeremy Hylton 2000-12-14 14:53:02 +00:00
parent 0bb1267cae
commit 4be092d93e
1 changed files with 27 additions and 25 deletions

View File

@ -56,11 +56,9 @@ Specification
If a name is used within a code block, but it is not bound there 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 and is not declared global, the use is treated as a reference to
the nearest enclosing function region. A region is visible from a the nearest enclosing function region. (Note: If a region is
block is all enclosing blocks are introduced by function contained within a class definition, the name bindings that occur
defintions. (Note: If a region is contained within a class in the class block are not visible to enclosed functions.)
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 A class definition is an executable statement that may uses and
definitions of names. These references follow the normal rules definitions of names. These references follow the normal rules
@ -111,19 +109,19 @@ Discussion
name resolution rules are typical for statically scoped languages, name resolution rules are typical for statically scoped languages,
with three primary exceptions: with three primary exceptions:
- Class definitions hide names. - Names in class scope are not accessible.
- The global statement short-circuits the normal rules. - The global statement short-circuits the normal rules.
- Variables are not declared. - Variables are not declared.
Class definitions hide names. Names are resolved in the innermost Names in class scope are not accessible. Names are resolved in
enclosing function scope. If a class defintion occurs in a chain the innermost enclosing function scope. If a class defintion
of nested scopes, the resolution process skips class definitions. occurs in a chain of nested scopes, the resolution process skips
This rule prevents odd interactions between class attributes and class definitions. This rule prevents odd interactions between
local variable access. If a name binding operation occurs in a class attributes and local variable access. If a name binding
class defintion, it creates an attribute on the resulting class operation occurs in a class defintion, it creates an attribute on
object. To access this variable in a method, or in a function the resulting class object. To access this variable in a method,
nested within a method, an attribute reference must be used, or in a function nested within a method, an attribute reference
either via self or via the class name. must be used, either via self or via the class name.
An alternative would have been to allow name binding in class An alternative would have been to allow name binding in class
scope to behave exactly like name binding in function scope. This 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. code and the environment in which to resolve free variables.
There are a variety of implementation alternatives for closures. There are a variety of implementation alternatives for closures.
One possibility is to use a static link from a nested function to Two typical ones are nested closures and flat closures. Nested
its enclosing environment. This implementation requires several closures use a static link from a nested function to its enclosing
links to be followed if there is more than one level of nesting environment. This implementation requires several links to be
and keeps many garbage objects alive longer than necessary. 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 Flat closures are roughly similar to the default argument hack
the default argument hack currently used for lambda support. Each currently used for lambda support. Each function object would
function object would have a func_env slot that holds a tuple of have a func_env slot that holds a tuple of free variable bindings.
free variable bindings. The code inside the function would use The code inside the function would use LOAD_ENV to access these
LOAD_ENV to access these bindings rather than the typical bindings rather than the typical LOAD_FAST.
LOAD_FAST.
The problem with this approach is that rebindings are not visible The problem with this approach is that rebindings are not visible
to the nested function. Consider the following example: to the nested function. Consider the following example:
@ -329,6 +327,10 @@ Implementation
definition time. This is the default argument hack, but not definition time. This is the default argument hack, but not
actual name resolution based on statically nested scopes. 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 It is not clear whether the current 1-pass Python compiler can
determine which references are to globals and which are references determine which references are to globals and which are references
to enclosing scopes. It may be possible to make minimal changes to enclosing scopes. It may be possible to make minimal changes