[Python-checkins] CVS: python/nondist/peps pep-0203.txt,1.2,1.3

Thomas Wouters python-dev@python.org
Sun, 16 Jul 2000 09:07:31 -0700


Update of /cvsroot/python/python/nondist/peps
In directory slayer.i.sourceforge.net:/tmp/cvs-serv29324

Modified Files:
	pep-0203.txt 
Log Message:

Incomplete version of the augmented assignment PEP. It currently includes
only the arguments for/against inclusion of augmented assignment in Python,
not yet the technical details. I decided to upload this half-completed
version to give people some time to respond before I finish it :-)

Feel free to bring up any and all arguments. The point of the PEP is to
archive those, after all!



Index: pep-0203.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0203.txt,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** pep-0203.txt	2000/07/14 03:30:20	1.2
--- pep-0203.txt	2000/07/16 16:07:29	1.3
***************
*** 8,11 ****
--- 8,153 ----
  
  
+ Introduction
+ 
+     This PEP describes the `augmented assignment' proposal for Python
+     2.0.  This PEP tracks the status and ownership of this feature,
+     slated for introduction in Python 2.0.  It contains a description
+     of the feature and outlines changes necessary to support the
+     feature.  This PEP summarizes discussions held in mailing list
+     forums, and provides URLs for further information, where
+     appropriate.  The CVS revision history of this file contains the
+     definitive historical record.
+ 
+ 
+ 
+ The Origin of Augmented Assignment
+ 
+     Augmented assignment refers to binary operators that combine two
+     existing operators: the assignment operator, and one of the binary
+     operators. Its origins lie in other programming languages, most
+     notably `C', where it was defined for performance reasons. They
+     are meant to replace the repetetive syntax of, for instance,
+     adding the number '1' to a variable:
+     
+       x = x + 1;
+       
+     with an expression that is shorter, less error-prone and easier to
+     optimize (by the compiler):
+     
+       x += 1;
+       
+     The same goes for all other binary operands, resulting in the
+     following augmented assignment operator list, based on Python's
+     current binary operator list:
+ 
+       +=, -=, /=, *=, %=, **=, >>=, <<=, &=, |=, ^=
+     
+     See the documentation of each operator on what they do.
+ 
+      
+ 
+ Augmented Assignment in Python
+ 
+     The traditional reasons for augmented assignment, readability and
+     optimization, are not as obvious in Python, for several reasons.
+     
+      - Numbers are immutable, they cannot be changed. In other
+        programming languages, a variable holds a value, and altering
+        the variable changes the value it holds. In Python, variables
+        hold `references' to values, and altering an immutable value
+        means changing the variable, not what it points to.
+ 
+      - Assignment is a different operation in Python. In most
+        languages, variables are containers, and assignment copies a
+        value into that container. In Python, assignment binds a value
+        to a name, it does not copy the value into a new storage space.
+        
+      - The augmented assignment operators map fairly directly into the
+        underlying hardware. Python does not deal directly with the
+        hardware it runs on, so this `natural inclusion' does not make
+        sense.
+ 
+      - The augmented assigment syntax is subtly different in more
+        complex expressions. What to do, for instance, in a case such
+        as this:
+        
+        seq[i:calc(seq, i)] *= r
+        
+        It is unclear whether 'seq' gets indexed once or twice, and
+        whether 'calc' gets called once or twice.
+ 
+ 
+ 
+ Normal operators
+ 
+     There are, however, good reasons to include augented assignment. 
+     One of these has to do with Python's way of handling operators. In
+     Python, a user defined class can implement one or more of the
+     binary operators by supplying a 'magic' method name. For instance,
+     for a class to support '<instance> + <object>', the '__add__'
+     method should be defined. This method should return a new object,
+     which is the result of the expression.
+     
+     For the case of '<object> + <instance>', where 'object' does not
+     have an '__add__' method, the class can define a '__radd__'
+     method, which then should behave exactly as '__add__'. Indeed,
+     '__radd__' is often a different name for the same method.
+     
+     For C extention types, a similar technique is available, through
+     the PyNumberMethods and PySequenceMethods members of the PyType
+     structure.
+ 
+     However, the problem with this approach is that the '__add__'
+     method cannot know in what context it is called. It cannot tell
+     whether it should create a new object, or whether it is allowed to
+     modify itself. (As would be the case in 'x = x + 1') As a result,
+     the '__add__' method, and all other such 'magic' methods, should
+     always return a new object. For large objects, this can be very
+     inefficient.
+     
+     This inefficiency is often solved by adding a method that does the
+     appropriate modification 'in-place'. List objects, for instance,
+     have the 'extend' method that behaves exactly as the '+' operator,
+     except the operation is done on the list itself, instead of on a
+     copy.
+ 
+     The augmented assignment syntax can support this behaviour
+     explicitly. When the magic method for 'in-place' operation are
+     missing, it can fall back to the normal methods for that
+     operation, maintaining full backward compatibility even when
+     mixing the new syntax with old objects.
+ 
+     The other benifit of augmented assignment is readability. After
+     the general concept of augmented assignment is grasped, all the
+     augmented assigment operators instantly become obvious. There is
+     no need for non-obvious and non-standard method names to implement
+     efficient, in-place operations, and there is no need to check the
+     type of an object before operating on it: the augmented assignment
+     will work for all types that implement that basic operation, not
+     merely those that implement the augmented variant.
+     
+     And the last problem with augmented assignment, what to do with
+     indexes and function calls in the expression, can be solved in a
+     very Pythonic manner: if it looks like it's only called once, it
+     *is* only called once. Taking this expression:
+     
+     seq[func(x)] += x
+     
+     The function 'func' is called once, and 'seq' is indexed twice:
+     once to retrieve the value (__getitem__), and once to store it
+     (__setitem__). So the expression can be rewritten as:
+     
+     tmp = func(x)
+     seq[tmp] = seq[tmp] + x
+     
+     The augmented assignment form of this expression is much more
+     readable.
+     
+ 
+ 
+ 
+ 
+ 
+ 
  Local Variables:
  mode: indented-text