added PEP 326, A Case for All, by Josiah Carlson
This commit is contained in:
parent
ac8a18b42f
commit
f5cddb1e9c
|
@ -121,6 +121,7 @@ Index by Category
|
|||
S 323 Copyable Iterators Martelli
|
||||
S 324 popen5 - New POSIX process module Astrand
|
||||
S 325 Resource-Release Support for Generators Pedroni
|
||||
S 326 A Case for All Carlson
|
||||
S 754 IEEE 754 Floating Point Special Values Warnes
|
||||
|
||||
Finished PEPs (done, implemented in CVS)
|
||||
|
@ -343,6 +344,7 @@ Numerical Index
|
|||
S 323 Copyable Iterators Martelli
|
||||
S 324 popen5 - New POSIX process module Astrand
|
||||
S 325 Resource-Release Support for Generators Pedroni
|
||||
S 326 A Case for All Carlson
|
||||
SR 666 Reject Foolish Indentation Creighton
|
||||
S 754 IEEE 754 Floating Point Special Values Warnes
|
||||
|
||||
|
@ -370,6 +372,7 @@ Owners
|
|||
Barrett, Paul barrett@stsci.edu
|
||||
Baxter, Anthony anthony@interlink.com.au
|
||||
Bellman, Thomas bellman+pep-divmod@lysator.liu.se
|
||||
Carlson, Josiah jcarlson@uci.edu
|
||||
Carroll, W Isaac icarroll@pobox.com
|
||||
Cole, Dave djc@object-craft.com.au
|
||||
Craig, Christopher python-pep@ccraig.org
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
PEP: 326
|
||||
Title: A Case for All
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Josiah Carlson <jcarlson@uci.edu>
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 20-Dec-2003
|
||||
Python-Version: 2.4
|
||||
Post-History: 20-Dec-2003, 03-Jan-2004
|
||||
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
This PEP proposes a new named constant or built-in: ``All``.
|
||||
|
||||
Users of Python have had the constant None, which represents a lack of
|
||||
value, for quite some time (possibly from the beginning, this is
|
||||
unknown to the author at the current time). The author believes that
|
||||
``All`` should be introduced in order to represent a functionally
|
||||
infinite value, with similar behavior corresponding to None.
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
||||
While None can be used as an absolute minimum that any value can
|
||||
attain [1]_, there does not exist an equivalent absolute maximum. For
|
||||
example::
|
||||
|
||||
>>> print min(None, -2**1000)
|
||||
None
|
||||
|
||||
All comparisons including None and another object results in None
|
||||
being the smaller of the two.
|
||||
|
||||
However, there does not exist a value such that the comparison of any
|
||||
other object results in the constant being the larger of the two.
|
||||
What is commonly done to deal with such cases, is to set a value in a
|
||||
script that is larger than the author ever expects the input to reach,
|
||||
and hope that it isn't reached.
|
||||
|
||||
Guido has brought up [2]_ the fact that there exists two constants
|
||||
that can be used in the interim: sys.maxint and floating point
|
||||
positive infinity (1e309 will evaluate to positive infinity).
|
||||
However, each has their drawbacks. On most architectures sys.maxint
|
||||
is arbitrarily small (2**31-1 or 2**63-1), and can be easily eclipsed
|
||||
by large 'long' integers or floating point numbers. Furthermore,
|
||||
comparing long integers larger than the largest floating point number
|
||||
representable against any float will result in an exception being
|
||||
raised::
|
||||
|
||||
>>> cmp(1.0, 10**309)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
OverflowError: long int too large to convert to float
|
||||
|
||||
Even when large integers are compared against positive infinity::
|
||||
|
||||
>>> cmp(1e309, 10**309)
|
||||
Traceback (most recent call last):
|
||||
File "<stdin>", line 1, in ?
|
||||
OverflowError: long int too large to convert to float
|
||||
|
||||
Introducing an ``All`` built-in that works as described does not take
|
||||
much effort. A sample Python implementation is included.
|
||||
|
||||
|
||||
Motivation
|
||||
==========
|
||||
|
||||
There are hundreds of algorithms that begin by initializing some set
|
||||
of values to a logical (or numeric) infinity. Python lacks a positive
|
||||
infinity that works consistently or really is the largest value that
|
||||
can be attained. By adding the ``All`` constant (or built-in), Python
|
||||
would have a real maximum value, and such algorithms can become
|
||||
clearer due to the reduction of special cases.
|
||||
|
||||
Take for example, finding the minimum in a sequence::
|
||||
|
||||
def findmin_Num(seq):
|
||||
BIG = 0
|
||||
cur = BIG
|
||||
for obj in seq:
|
||||
if cur == BIG:
|
||||
cur = obj
|
||||
BIG = max(cur, BIG) + 1
|
||||
else:
|
||||
cur = min(cur, obj)
|
||||
return cur
|
||||
|
||||
def findmin_None(seq):
|
||||
cur = None
|
||||
for obj in seq:
|
||||
if obj < cur or (cur is None):
|
||||
cur = obj
|
||||
if cur is None:
|
||||
return cur
|
||||
return cur
|
||||
|
||||
def findmin_All(seq):
|
||||
cur = All
|
||||
for obj in seq:
|
||||
cur = min(obj, cur)
|
||||
return cur
|
||||
|
||||
Guido brought up the idea of just negating everything and comparing
|
||||
[2]_. Certainly this does work when using numbers, but it does not
|
||||
remove the special case (actually adds one) and results in the code
|
||||
being less readable. ::
|
||||
|
||||
#we have All available
|
||||
a = min(a, b)
|
||||
|
||||
#we don't have All available
|
||||
if a is not None:
|
||||
if b is None:
|
||||
a = b
|
||||
else:
|
||||
a = -max(-a, -b)
|
||||
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
::
|
||||
|
||||
class _AllType(object):
|
||||
|
||||
def __cmp__(self, other):
|
||||
if isinstance(other, self.__class__):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def __repr__(self):
|
||||
return 'All'
|
||||
|
||||
import sys
|
||||
sys.modules['__builtin__'].All = _AllType()
|
||||
|
||||
Results of Test Run in Python 2.3.3::
|
||||
|
||||
>>> max(All, 2**65536)
|
||||
All
|
||||
>>> min(All, 2**65536)
|
||||
20035299304068464649790...
|
||||
(lines removed for brevity)
|
||||
...72339445587895905719156736L
|
||||
>>> max(All, None)
|
||||
All
|
||||
>>> min(All, None)
|
||||
>>> print min(All, None)
|
||||
None
|
||||
>>> bool(All)
|
||||
True
|
||||
>>> not None
|
||||
1
|
||||
>>> not All
|
||||
0
|
||||
|
||||
|
||||
Open Issues
|
||||
===========
|
||||
|
||||
``All`` seemed to be an awkward object to various Python developers on
|
||||
the python-dev mailing list. The author hopes that with this updated
|
||||
PEP, developers will no longer find ``All`` awkward.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] RE: [Python-Dev] Re: Got None. Maybe Some?, Peters, Tim
|
||||
(http://mail.python.org/pipermail/python-dev/2003-December/041374.html)
|
||||
|
||||
.. [2] Re: [Python-Dev] Got None. Maybe Some?, von Rossum, Guido
|
||||
(http://mail.python.org/pipermail/python-dev/2003-December/041352.html)
|
||||
|
||||
.. [3] [Python-Dev] Re: Got None. Maybe Some?, Reedy, Terry
|
||||
(http://mail.python.org/pipermail/python-dev/2003-December/041337.html)
|
||||
|
||||
|
||||
Changes
|
||||
=======
|
||||
|
||||
Added this section.
|
||||
|
||||
Renamed ``Some`` to ``All``: Some was an arbitrary name that suffered
|
||||
from being unclear. [3]_
|
||||
|
||||
Made ``All`` a subclass of object in order for it to become a new
|
||||
style class.
|
||||
|
||||
Removed mathematical negation and casting to float in Open Issues.
|
||||
None is not a number and is not treated as one, ``All`` shouldn't be
|
||||
either.
|
||||
|
||||
Added Motivation section.
|
||||
|
||||
Changed markup to reStructuredText.
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 74
|
||||
End:
|
Loading…
Reference in New Issue