[Python-checkins] CVS: python/nondist/peps pep-0227.txt,1.7,1.8

Guido van Rossum gvanrossum@users.sourceforge.net
Thu, 19 Apr 2001 12:36:15 -0700


Update of /cvsroot/python/python/nondist/peps
In directory usw-pr-cvs1:/tmp/cvs-serv3876

Modified Files:
	pep-0227.txt 
Log Message:
Updated for clarity and to reflect reality.  Jeremy, there are still
XXX bits in here.  Also, shouldn't the status be updated to Final?


Index: pep-0227.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0227.txt,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -r1.7 -r1.8
*** pep-0227.txt	2001/02/26 20:08:05	1.7
--- pep-0227.txt	2001/04/19 19:36:13	1.8
***************
*** 11,26 ****
  Abstract
  
!     This PEP proposes the addition of statically nested scoping
!     (lexical scoping) for Python 2.1.  The current language definition
!     defines exactly three namespaces that are used to resolve names --
!     the local, global, and built-in namespaces.  The addition of
!     nested scopes would allow resolution of unbound local names in
!     enclosing functions' namespaces.
! 
!     One consequence of this change that will be most visible to Python
!     programs is that lambda statements could reference variables in
!     the namespaces where the lambda is defined.  Currently, a lambda
!     statement uses default arguments to explicitly creating bindings
!     in the lambda's namespace.
  
  Introduction
--- 11,30 ----
  Abstract
  
!     This PEP describes the addition of statically nested scoping
!     (lexical scoping) for Python 2.2, and as an source level option
!     for python 2.1.  In addition, Python 2.1 will issue warnings about
!     constructs whose meaning may change when this feature is enabled.
! 
!     The old language definition (2.0 and before) defines exactly three
!     namespaces that are used to resolve names -- the local, global,
!     and built-in namespaces.  The addition of nested scopes allows
!     resolution of unbound local names in enclosing functions'
!     namespaces.
! 
!     The most visible consequence of this change is that lambdas (and
!     other nested functions) can reference variables defined in the
!     surrounding namespace.  Currently, lambdas must often use default
!     arguments to explicitly creating bindings in the lambda's
!     namespace.
  
  Introduction
***************
*** 30,34 ****
      effect with Python 2.2.  These semantics will also be available in
      Python 2.1 by adding "from __future__ import nested_scopes" to the
!     top of a module.
  
      The Python 2.0 definition specifies exactly three namespaces to
--- 34,38 ----
      effect with Python 2.2.  These semantics will also be available in
      Python 2.1 by adding "from __future__ import nested_scopes" to the
!     top of a module.  (See PEP 236.)
  
      The Python 2.0 definition specifies exactly three namespaces to
***************
*** 40,44 ****
      binding that hides the binding in B).
  
!     The specification introduces rules for lexical scoping that are
      common in Algol-like languages.  The combination of lexical
      scoping and existing support for first-class functions is
--- 44,48 ----
      binding that hides the binding in B).
  
!     This specification introduces rules for lexical scoping that are
      common in Algol-like languages.  The combination of lexical
      scoping and existing support for first-class functions is
***************
*** 46,69 ****
  
      The changed scoping rules address two problems -- the limited
!     utility of lambda statements and the frequent confusion of new
!     users familiar with other languages that support lexical scoping,
!     e.g. the inability to define recursive functions except at the
!     module level.
  
!     The lambda statement introduces an unnamed function that contains
!     a single statement.  It is often used for callback functions.  In
      the example below (written using the Python 2.0 rules), any name
      used in the body of the lambda must be explicitly passed as a
      default argument to the lambda.
  
!     from Tkinter import *
!     root = Tk()
!     Button(root, text="Click here",
!            command=lambda root=root: root.test.configure(text="..."))
  
      This approach is cumbersome, particularly when there are several
      names used in the body of the lambda.  The long list of default
!     arguments obscure the purpose of the code.  The proposed solution,
!     in crude terms, implements the default argument approach
      automatically.  The "root=root" argument can be omitted.
  
--- 50,73 ----
  
      The changed scoping rules address two problems -- the limited
!     utility of lambda expressions (and nested functions in general),
!     and the frequent confusion of new users familiar with other
!     languages that support nested lexical scopes, e.g. the inability
!     to define recursive functions except at the module level.
  
!     The lambda expression yields an unnamed function that evaluates a
!     single expression.  It is often used for callback functions.  In
      the example below (written using the Python 2.0 rules), any name
      used in the body of the lambda must be explicitly passed as a
      default argument to the lambda.
  
!       from Tkinter import *
!       root = Tk()
!       Button(root, text="Click here",
!              command=lambda root=root: root.test.configure(text="..."))
  
      This approach is cumbersome, particularly when there are several
      names used in the body of the lambda.  The long list of default
!     arguments obscures the purpose of the code.  The proposed
!     solution, in crude terms, implements the default argument approach
      automatically.  The "root=root" argument can be omitted.
  
***************
*** 73,78 ****
      previously resolved using the global namespace will be resolved
      using the local namespace of an enclosing function.  In Python
!     2.1, warnings will be issued for all program statement that will
!     behave differently.
  
  Specification
--- 77,82 ----
      previously resolved using the global namespace will be resolved
      using the local namespace of an enclosing function.  In Python
!     2.1, warnings will be issued for all statements that will behave
!     differently.
  
  Specification
***************
*** 88,110 ****
      block containing the use.
  
!     The name binding operations are assignment, class and function
!     definition, and import statements.  Each assignment or import
!     statement occurs within a block defined by a class or function
!     definition or at the module level (the top-level code block).
! 
!     If a name binding operation occurs anywhere within a code block,
!     all uses of the name within the block are treated as references to
!     the current block.  (Note: This can lead to errors when a name is
!     used within a block before it is bound.)
  
      If the global statement occurs within a block, all uses of the
      name specified in the statement refer to the binding of that name
      in the top-level namespace.  Names are resolved in the top-level
!     namespace by searching the global namespace, the namespace of the
!     module containing the code block, and the builtin namespace, the
!     namespace of the module __builtin__.  The global namespace is
!     searched first.  If the name is not found there, the builtin
!     namespace is searched.  The global statement must precede all uses
!     of the name.
  
      If a name is used within a code block, but it is not bound there
--- 92,115 ----
      block containing the use.
  
!     The name binding operations are argument declaration, assignment,
!     class and function definition, import statements, for statements,
!     and except clauses.  Each name binding occurs within a block
!     defined by a class or function definition or at the module level
!     (the top-level code block).
! 
!     If a name is bound anywhere within a code block, all uses of the
!     name within the block are treated as references to the current
!     block.  (Note: This can lead to errors when a name is used within
!     a block before it is bound.)
  
      If the global statement occurs within a block, all uses of the
      name specified in the statement refer to the binding of that name
      in the top-level namespace.  Names are resolved in the top-level
!     namespace by searching the global namespace, i.e. the namespace of
!     the module containing the code block, and in the builtin
!     namespace, i.e. the namespace of the __builtin__ module.  The
!     global namespace is searched first.  If the name is not found
!     there, the builtin namespace is searched.  The global statement
!     must precede all uses of the name.
  
      If a name is used within a code block, but it is not bound there
***************
*** 124,127 ****
--- 129,133 ----
  
      Function definition: def name ...
+     Argument declaration: def f(...name...), lambda ...name...
      Class definition: class name ...
      Assignment statement: name = ...    
***************
*** 131,141 ****
          clauses
  
-     The arguments of a function are also local.
- 
      There are several cases where Python statements are illegal when
      used in conjunction with nested scopes that contain free
      variables.
  
!     If a variable is referenced in an enclosing scope, it is an error
      to delete the name.  The compiler will raise a SyntaxError for
      'del name'.
--- 137,145 ----
          clauses
  
      There are several cases where Python statements are illegal when
      used in conjunction with nested scopes that contain free
      variables.
  
!     If a variable is referenced in an enclosed scope, it is an error
      to delete the name.  The compiler will raise a SyntaxError for
      'del name'.
***************
*** 152,158 ****
  
      If a name bound in a function scope is also the name of a module
!     global name or a standard builtin name and the function contains a
!     nested function scope that references the name, the compiler will
!     issue a warning.  The name resolution rules will result in
      different bindings under Python 2.0 than under Python 2.2.  The
      warning indicates that the program may not run correctly with all
--- 156,162 ----
  
      If a name bound in a function scope is also the name of a module
!     global name or a standard builtin name, and the function contains
!     a nested function scope that references the name, the compiler
!     will issue a warning.  The name resolution rules will result in
      different bindings under Python 2.0 than under Python 2.2.  The
      warning indicates that the program may not run correctly with all
***************
*** 190,195 ****
      The global statement short-circuits the normal rules.  Under the
      proposal, the global statement has exactly the same effect that it
!     does for Python 2.0.  Its behavior is preserved for backwards
!     compatibility.  It is also noteworthy because it allows name
      binding operations performed in one block to change bindings in
      another block (the module).
--- 194,198 ----
      The global statement short-circuits the normal rules.  Under the
      proposal, the global statement has exactly the same effect that it
!     does for Python 2.0.  It is also noteworthy because it allows name
      binding operations performed in one block to change bindings in
      another block (the module).
***************
*** 306,312 ****
      standard library during the implementation of nested scopes.
  
!     To address this problem, which is unlikely to occur often, a
!     static analysis tool that detects affected code will be written.
!     The detection problem is straightforward.
  
      The other compatibility problem is caused by the use of 'import *'
--- 309,315 ----
      standard library during the implementation of nested scopes.
  
!     To address this problem, which is unlikely to occur often, the
!     Python 2.1 compiler (when nested scopes are not enabled) issues a
!     warning.
  
      The other compatibility problem is caused by the use of 'import *'
***************
*** 342,346 ****
  
      Since each interpretation is problematic and the exact meaning
!     ambiguous, the compiler raises an exception.
  
      A brief review of three Python projects (the standard library,
--- 345,350 ----
  
      Since each interpretation is problematic and the exact meaning
!     ambiguous, the compiler raises an exception.  The Python 2.1
!     compiler issues a warning when nested scopes are not enabled.
  
      A brief review of three Python projects (the standard library,
***************
*** 421,429 ****
      rebinding of names in enclosing scopes, but the primary reason
      that it is not allowed in the current proposal is that Guido is
!     opposed to it.  It is difficult to support, because it would
!     require a new mechanism that would allow the programmer to specify
!     that an assignment in a block is supposed to rebind the name in an
!     enclosing block; presumably a keyword or special syntax (x := 3)
!     would make this possible.
  
      The proposed rules allow programmers to achieve the effect of
--- 425,436 ----
      rebinding of names in enclosing scopes, but the primary reason
      that it is not allowed in the current proposal is that Guido is
!     opposed to it.  His motivation: it is difficult to support,
!     because it would require a new mechanism that would allow the
!     programmer to specify that an assignment in a block is supposed to
!     rebind the name in an enclosing block; presumably a keyword or
!     special syntax (x := 3) would make this possible.  Given that this
!     would encourage the use of local variables to hold state that is
!     better stored in a class instance, it's not worth adding new
!     syntax to make this possible (in Guido's opinion).
  
      The proposed rules allow programmers to achieve the effect of
***************
*** 451,456 ****
  Implementation
  
      The implementation for C Python uses flat closures [1].  Each def
!     or lambda statement that is executed will create a closure if the
      body of the function or any contained function has free
      variables.  Using flat closures, the creation of closures is
--- 458,465 ----
  Implementation
  
+     XXX Jeremy, is this still the case?
+ 
      The implementation for C Python uses flat closures [1].  Each def
!     or lambda expression that is executed will create a closure if the
      body of the function or any contained function has free
      variables.  Using flat closures, the creation of closures is