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

Barry Warsaw python-dev@python.org
Tue, 22 Aug 2000 22:42:00 -0700


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

Modified Files:
	pep-0204.txt 
Log Message:
Editorial review, including:

    - Rearrange and standardize headers
    - Removed ^L's
    - Spellchecked
    - Indentation and formatting
    - Added reference to PEP 202

Thomas, if the open issues have been decided, they can be `closed' in
this PEP, and then it should probably be marked as Accepted.


Index: pep-0204.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0204.txt,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** pep-0204.txt	2000/07/26 04:11:22	1.3
--- pep-0204.txt	2000/08/23 05:41:57	1.4
***************
*** 2,17 ****
  Title: Range Literals
  Version: $Revision$
! Owner: thomas@xs4all.net (Thomas Wouters)
! Python-Version: 2.0
  Status: Draft
  
  
- 
  Introduction
  
!     This PEP describes the `range literal' 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
--- 2,19 ----
  Title: Range Literals
  Version: $Revision$
! Author: thomas@xs4all.net (Thomas Wouters)
  Status: Draft
+ Type: Standards Track
+ Python-Version: 2.0
+ Created: 14-Jul-2000
+ Post-History:
  
  
  Introduction
  
!     This PEP describes the `range literal' 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
***************
*** 20,24 ****
  
  
- 
  List ranges
  
--- 22,25 ----
***************
*** 27,37 ****
      sequence directly:
      
!     >>> l = ['a', 'b', 'c', 'd']
!     >>> for item in l:
!     ...     print item
!     a
!     b
!     c
!     d
      
      However, this solution is not always prudent.  Firstly, problems
--- 28,38 ----
      sequence directly:
      
!         >>> l = ['a', 'b', 'c', 'd']
!         >>> for item in l:
!         ...     print item
!         a
!         b
!         c
!         d
      
      However, this solution is not always prudent.  Firstly, problems
***************
*** 57,79 ****
      this:
      
!     >>> for i in range(len(l)):
!     ...     print l[i]
!     a
!     b
!     c
!     d
      
      Or, to start at the second element of `l' and processing only
      every second element from then on:
      
!     >>> for i in range(1, len(l), 2):
!     ...     print l[i]
!     b
!     d
      
      There are several disadvantages with this approach:
      
!     - Clarity of purpose: Adding another functioncall, possibly with
!       extra arithmatic to determine the desired length and step of the
        list, does not improve readability of the code.  Also, it is
        possible to `shadow' the builtin `range' function by supplying a
--- 58,80 ----
      this:
      
!         >>> for i in range(len(l)):
!         ...     print l[i]
!         a
!         b
!         c
!         d
      
      Or, to start at the second element of `l' and processing only
      every second element from then on:
      
!         >>> for i in range(1, len(l), 2):
!         ...     print l[i]
!         b
!         d
      
      There are several disadvantages with this approach:
      
!     - Clarity of purpose: Adding another function call, possibly with
!       extra arithmetic to determine the desired length and step of the
        list, does not improve readability of the code.  Also, it is
        possible to `shadow' the builtin `range' function by supplying a
***************
*** 83,87 ****
      - Efficiency: because the `range' function can be overridden, the
        Python compiler cannot make assumptions about the for-loop, and
!       has to maintain a seperate loop counter.
        
      - Consistency: There already is a syntax that is used to denote
--- 84,88 ----
      - Efficiency: because the `range' function can be overridden, the
        Python compiler cannot make assumptions about the for-loop, and
!       has to maintain a separate loop counter.
        
      - Consistency: There already is a syntax that is used to denote
***************
*** 92,96 ****
  
  
- 
  Slice Indices
  
--- 93,96 ----
***************
*** 101,108 ****
      the original sequence.  This is done using a `range notation':
      
!     >>> l[2:4]
!     ['c', 'd']
      
!     This range notation consists of zero, one or two indices seperated
      by a colon.  The first index is the `start' index, the second the
      `end'.  When either is left out, they default to respectively the
--- 101,108 ----
      the original sequence.  This is done using a `range notation':
      
!         >>> l[2:4]
!         ['c', 'd']
      
!     This range notation consists of zero, one or two indices separated
      by a colon.  The first index is the `start' index, the second the
      `end'.  When either is left out, they default to respectively the
***************
*** 113,126 ****
      by most builtin types, if it were, it would work as follows:
      
!     >>> l[1:4:2]
!     ['b', 'd']
  
      The third `argument' to the slice syntax is exactly the same as
!     the `step' argument to range().  The underlying mechanisms of
!     standard and these extended slices are sufficiently different and
!     inconsistent that many classes and extensions outside of
      mathematical packages do not implement support for the extended
!     variant, and this should definately be resolved, but this is
!     beyond the scope of this PEP.
      
      Extended slices do show, however, that there is already a
--- 113,126 ----
      by most builtin types, if it were, it would work as follows:
      
!         >>> l[1:4:2]
!         ['b', 'd']
  
      The third `argument' to the slice syntax is exactly the same as
!     the `step' argument to range().  The underlying mechanisms of the
!     standard, and these extended slices, are sufficiently different
!     and inconsistent that many classes and extensions outside of
      mathematical packages do not implement support for the extended
!     variant.  While this should be resolved, it is beyond the scope of
!     this PEP.
      
      Extended slices do show, however, that there is already a
***************
*** 133,137 ****
        
      - It is consistent with the other use of ranges in Python
!       (slices.)
        
      - Because it is built-in syntax, instead of a builtin function, it
--- 133,137 ----
        
      - It is consistent with the other use of ranges in Python
!       (e.g. slices).
        
      - Because it is built-in syntax, instead of a builtin function, it
***************
*** 141,145 ****
  
  
- 
  The Proposed Solution
  
--- 141,144 ----
***************
*** 148,157 ****
      range literals:
      
!     >>> [1:10]
!     [1, 2, 3, 4, 5, 6, 7, 8, 9]
!     >>> [:5]
!     [0, 1, 2, 3, 4]
!     >>> [5:1:-1]
!     [5, 4, 3, 2]
      
      There is one minor difference between range literals and the slice
--- 147,156 ----
      range literals:
      
!         >>> [1:10]
!         [1, 2, 3, 4, 5, 6, 7, 8, 9]
!         >>> [:5]
!         [0, 1, 2, 3, 4]
!         >>> [5:1:-1]
!         [5, 4, 3, 2]
      
      There is one minor difference between range literals and the slice
***************
*** 162,166 ****
      
  
- 
  Reference Implementation
  
--- 161,164 ----
***************
*** 178,268 ****
      calls.
  
!     PyObject * PyList_FromRange(long start, long end, long step)
!     builds a list from start, end and step, returning NULL if an error
!     occurs.
!     
!     long PyList_GetLenOfRange(long start, long end, long step) is a
!     helper function to determine the length of a range.  It was
!     previously a static function in bltinmodule.c, but is now
!     necessary in both listobject.c and bltinmodule.c (for xrange).  It
!     is made non-static solely to avoid code duplication.
  
! 
  Open issues
  
!     One possible solution to the discrepancy of requiring the `end'
!     argument in range literals is to allow the range syntax to create
!     a `generator', rather than a list, such as the `xrange' builtin
!     function does.  However, a generator would not be a list, and it
!     would be impossible, for instance, to assign to items in the
!     generator, or append to it.
!     
!     The range syntax could conceivably be extended to include tuples,
!     immutable lists, which could then be safely implemented as
!     generators.  Especially for large number arrays, this may be a
!     desirable solution: generators require very little in the way of
!     storage and initialization, and there is only a small performance
!     impact in calculating and creating the appropriate number on
!     request.  (TBD: is there any at all ? Cursory testing suggests
!     equal performance even in the case of ranges of length 1.)
!     
!     However, even if idea was adopted, would it be wise to `special
!     case' the second argument, making it optional in one instance of
!     the syntax, and non-optional in other cases ?
  
  
!     Should it be possible to mix range syntax with normal list
!     literals, creating a single list, like so:
  
-     >>> [5, 6, 1:6, 7, 9]
      to create
-     [5, 6, 1, 2, 3, 4, 5, 7, 9]
  
  
!     How should range literals interact with another proposed new
!     feature, `list comprehensions', PEP-202 ? In specific, should it
!     be possible to create lists in list comprehensions, like so:
      
!     >>> [x:y for x in (1,2) y in (3, 4)]
  
!     Should this example return a single list with multiple ranges:
!     [1, 2, 1, 2, 3, 2, 2, 3]
  
!     Or a list of lists, like so:
!     [[1, 2], [1, 2, 3], [2], [2, 3]]
  
!     However, as the syntax and semantics of list comprehensions are
!     still subject of hot debate, these issues are probably best
!     addressed by the `list comprehensions' PEP.
!     
  
!     Range literals accept objects other than integers: it performs
!     PyInt_AsLong() on the objects passed in, so as long as the objects
!     can be coerced into integers, they will be accepted.  The
!     resulting list, however, is always composed of standard integers.
  
!     Should range literals create a list of the passed-in type ? It
!     might be desirable in the cases of other builtin types, such as
!     longs and strings:
!     
!     >>> [ 1L : 2L<<64 : 2<<32L ]    
!     >>> ["a":"z":"b"]
!     >>> ["a":"z":2]
!     
!     However, this might be too much `magic' to be obvious.  It might
!     also present problems with user-defined classes: even if the base
!     class can be found and a new instance created, the instance may
!     require additional arguments to __init__, causing the creation to
!     fail.
  
      
!     The PyList_FromRange() and PyList_GetLenOfRange() functions need
!     to be classified: are they part of the API, or should they be made
!     private functions ?
      
! 
  References:
  
      [1] http://sourceforge.net/patch/?func=detailpatch&patch_id=100902&group_id=5470
  
  
--- 176,273 ----
      calls.
  
!     PyList_FromRange() builds a list from start, end and step,
!     returning NULL if an error occurs.  Its prototype is:
! 
!         PyObject * PyList_FromRange(long start, long end, long step)
!     
!     PyList_GetLenOfRange() is a helper function used to determine the
!     length of a range.  Previously, it was a static function in
!     bltinmodule.c, but is now necessary in both listobject.c and
!     bltinmodule.c (for xrange).  It is made non-static solely to avoid
!     code duplication.  Its prototype is:
  
!         long PyList_GetLenOfRange(long start, long end, long step) 
! 
! 
  Open issues
  
!     - One possible solution to the discrepancy of requiring the `end'
!       argument in range literals is to allow the range syntax to
!       create a `generator', rather than a list, such as the `xrange'
!       builtin function does.  However, a generator would not be a
!       list, and it would be impossible, for instance, to assign to
!       items in the generator, or append to it.
! 
!       The range syntax could conceivably be extended to include tuples
!       (i.e. immutable lists), which could then be safely implemented
!       as generators.  This may be a desirable solution, especially for
!       large number arrays: generators require very little in the way
!       of storage and initialization, and there is only a small
!       performance impact in calculating and creating the appropriate
!       number on request.  (TBD: is there any at all? Cursory testing
!       suggests equal performance even in the case of ranges of length
!       1)
! 
!       However, even if idea was adopted, would it be wise to `special
!       case' the second argument, making it optional in one instance of
!       the syntax, and non-optional in other cases ?
  
+     - Should it be possible to mix range syntax with normal list
+       literals, creating a single list?  E.g.:
  
!           >>> [5, 6, 1:6, 7, 9]
  
      to create
  
+           [5, 6, 1, 2, 3, 4, 5, 7, 9]
  
!     - How should range literals interact with another proposed new
!       feature, `list comprehensions'[2]?  Specifically, should it be
!       possible to create lists in list comprehensions?  E.g.:
      
!           >>> [x:y for x in (1, 2) y in (3, 4)]
  
!       Should this example return a single list with multiple ranges:
  
!           [1, 2, 1, 2, 3, 2, 2, 3]
  
!       Or a list of lists, like so:
  
!           [[1, 2], [1, 2, 3], [2], [2, 3]]
  
!       However, as the syntax and semantics of list comprehensions are
!       still subject of hot debate, these issues are probably best
!       addressed by the `list comprehensions' PEP.
! 
!     - Range literals accept objects other than integers: it performs
!       PyInt_AsLong() on the objects passed in, so as long as the
!       objects can be coerced into integers, they will be accepted.
!       The resulting list, however, is always composed of standard
!       integers.
! 
!       Should range literals create a list of the passed-in type?  It
!       might be desirable in the cases of other builtin types, such as
!       longs and strings:
  
+           >>> [ 1L : 2L<<64 : 2<<32L ]    
+           >>> ["a":"z":"b"]
+           >>> ["a":"z":2]
+ 
+       However, this might be too much `magic' to be obvious.  It might
+       also present problems with user-defined classes: even if the
+       base class can be found and a new instance created, the instance
+       may require additional arguments to __init__, causing the
+       creation to fail.
      
!     - The PyList_FromRange() and PyList_GetLenOfRange() functions need
!       to be classified: are they part of the API, or should they be
!       made private functions?
      
! 
  References:
  
      [1] http://sourceforge.net/patch/?func=detailpatch&patch_id=100902&group_id=5470
+     [2] PEP 202, List Comprehensions, pep-0202.txt
+