Incorporated review feedback. Added Jython argument. Added mention
of standard library. Added clarification that "if <list>:" remains as valid as ever. Minor rewordings all over, got rid of "e.g." again.
This commit is contained in:
parent
4e4e4e8c29
commit
f9691ffbc7
119
pep-0285.txt
119
pep-0285.txt
|
@ -32,33 +32,88 @@ Review
|
||||||
|
|
||||||
1) Should this PEP be accepted at all.
|
1) Should this PEP be accepted at all.
|
||||||
|
|
||||||
|
=> The majority of reviewers so far are in favor, ranging from +0
|
||||||
|
(don't hate it) to 1 (yes please). Votes against are mixed:
|
||||||
|
some are against all change, some think it's not needed, some
|
||||||
|
think it will just add more confusion or complexity, some have
|
||||||
|
irrational fears about code breakage based on misunderstanding
|
||||||
|
the PEP (believing it adds reserved words, or believing it will
|
||||||
|
require you to write "if bool(x):" where previously "if x:"
|
||||||
|
worked; neither belief is true).
|
||||||
|
|
||||||
2) Should str(True) return "True" or "1": "1" might reduce
|
2) Should str(True) return "True" or "1": "1" might reduce
|
||||||
backwards compatibility problems, but looks strange to me.
|
backwards compatibility problems, but looks strange to me.
|
||||||
(repr(True) would always return "True".)
|
(repr(True) would always return "True".)
|
||||||
|
|
||||||
|
=> Most reviewers prefer str(True) == "True" (which may mean that
|
||||||
|
they don't appreciate the specific
|
||||||
|
|
||||||
3) Should the constants be called 'True' and 'False'
|
3) Should the constants be called 'True' and 'False'
|
||||||
(corresponding to None) or 'true' and 'false' (as in C++, Java
|
(corresponding to None) or 'true' and 'false' (as in C++, Java
|
||||||
and C99).
|
and C99).
|
||||||
|
|
||||||
|
=> There's no clear preference either way here, so I'll break the
|
||||||
|
tie by pronouncing False and True.
|
||||||
|
|
||||||
Most other details of the proposal are pretty much forced by the
|
Most other details of the proposal are pretty much forced by the
|
||||||
backwards compatibility requirement; e.g. True == 1 and
|
backwards compatibility requirement; for example, True == 1 and
|
||||||
True+1 == 2 must hold, else reams of existing code would break.
|
True+1 == 2 must hold, else reams of existing code would break.
|
||||||
|
|
||||||
Minor additional issues:
|
Minor additional issues:
|
||||||
|
|
||||||
4) Should we strive to eliminate non-Boolean operations on bools
|
4) Should we strive to eliminate non-Boolean operations on bools
|
||||||
in the future, through suitable warnings, so that e.g. True+1
|
in the future, through suitable warnings, so that for example
|
||||||
would eventually (e.g. in Python 3000 be illegal). Personally,
|
True+1 would eventually (in Python 3000) be illegal.
|
||||||
I think we shouldn't; 28+isleap(y) seems totally reasonable to
|
Personally, I think we shouldn't; 28+isleap(y) seems totally
|
||||||
me.
|
reasonable to me.
|
||||||
|
|
||||||
|
=> Most reviewers agree with me.
|
||||||
|
|
||||||
5) Should operator.truth(x) return an int or a bool. Tim Peters
|
5) Should operator.truth(x) return an int or a bool. Tim Peters
|
||||||
believes it should return an int because it's been documented
|
believes it should return an int because it's been documented
|
||||||
as such. I think it should return a bool; most other standard
|
as such. I think it should return a bool; most other standard
|
||||||
predicates (e.g. issubtype()) have also been documented as
|
predicates (like issubtype()) have also been documented as
|
||||||
returning 0 or 1, and it's obvious that we want to change those
|
returning 0 or 1, and it's obvious that we want to change those
|
||||||
to return a bool.
|
to return a bool.
|
||||||
|
|
||||||
|
=> Most reviewers agree with me. My take: operator.truth() exists
|
||||||
|
to force a Boolean context on its argument (it calls the C API
|
||||||
|
PyObject_IsTrue()). Whether the outcome is reported as int or
|
||||||
|
bool is secondary; if bool exists there's no reason not to use
|
||||||
|
it.
|
||||||
|
|
||||||
|
New issues brought up during the review:
|
||||||
|
|
||||||
|
6) Should bool inherit from int?
|
||||||
|
|
||||||
|
=> My take: in an ideal world, bool might be better implemented as
|
||||||
|
a separate integer type that knows how to perform mixed-mode
|
||||||
|
arithmetic. However, inheriting bool from int eases the
|
||||||
|
implementation enormously (in part since all C code that calls
|
||||||
|
PyInt_Check() will continue to work -- this returns true for
|
||||||
|
subclasses of int). Also, I believe in terms of
|
||||||
|
substitutability, this is right: code that requires an int can
|
||||||
|
be fed a bool and it will behave the same as 0 or 1. Code that
|
||||||
|
requires a bool may not work when it is given an int; for
|
||||||
|
example, 3 & 4 is 0, but both 3 and 4 are true when considered
|
||||||
|
as truth values.
|
||||||
|
|
||||||
|
7) Should the name 'bool' be changed?
|
||||||
|
|
||||||
|
=> Some reviewers argue for boolean instead of bool, because this
|
||||||
|
would be easier to understand (novices may have heard of
|
||||||
|
Boolean algebra but may not make the connection with bool) or
|
||||||
|
because they hate abbreviations. My take: Python uses
|
||||||
|
abbreviations judiciously (like 'def', 'int', 'dict') and I
|
||||||
|
don't think these are a burden to understanding.
|
||||||
|
|
||||||
|
One reviewer argues to make the name 'truth'. I find this an
|
||||||
|
unattractive name, and would actually prefer to reserve this
|
||||||
|
term (in documentation) for the more abstract concept of truth
|
||||||
|
values that already exists in Python. For example: "when a
|
||||||
|
container is interpreted as a truth value, an empty container
|
||||||
|
is considered false and a non-empty one is considered true."
|
||||||
|
|
||||||
|
|
||||||
Rationale
|
Rationale
|
||||||
|
|
||||||
|
@ -79,12 +134,16 @@ Rationale
|
||||||
Some external libraries (like databases and RPC packages) need to
|
Some external libraries (like databases and RPC packages) need to
|
||||||
be able to distinguish between Boolean and integral values, and
|
be able to distinguish between Boolean and integral values, and
|
||||||
while it's usually possible to craft a solution, it would be
|
while it's usually possible to craft a solution, it would be
|
||||||
easier if the language offered a standard Boolean type.
|
easier if the language offered a standard Boolean type. This also
|
||||||
|
applies to Jython: some Java classes have separately overloaded
|
||||||
|
methods or constructors for int and boolean arguments. The bool
|
||||||
|
type can be used to select the boolean variant.
|
||||||
|
|
||||||
The standard bool type can also serve as a way to force a value to
|
The standard bool type can also serve as a way to force a value to
|
||||||
be interpreted as a Boolean, which can be used to normalize
|
be interpreted as a Boolean, which can be used to normalize
|
||||||
Boolean values. Writing bool(x) is much clearer than "not not x"
|
Boolean values. When a Boolean value needs to be normalized to
|
||||||
and much more concise than
|
one of two values, bool(x) is much clearer than "not not x" and
|
||||||
|
much more concise than
|
||||||
|
|
||||||
if x:
|
if x:
|
||||||
return 1
|
return 1
|
||||||
|
@ -192,11 +251,31 @@ Specification
|
||||||
isdecimal() and isnumeric(), and the 'closed' attribute of file
|
isdecimal() and isnumeric(), and the 'closed' attribute of file
|
||||||
objects.
|
objects.
|
||||||
|
|
||||||
Note that subclassing from int means that True+1 is valid and
|
Because bool inherits from int, True+1 is valid and equals 2, and
|
||||||
equals 2, and so on. This is important for backwards
|
so on. This is important for backwards compatibility: because
|
||||||
compatibility: because comparisons and so on currently return
|
comparisons and so on currently return integer values, there's no
|
||||||
integer values, there's no way of telling what uses existing
|
way of telling what uses existing applications make of these
|
||||||
applications make of these values.
|
values.
|
||||||
|
|
||||||
|
It is expected that over time, the standard library will be
|
||||||
|
updated to use False and True when appropriate (but not to require
|
||||||
|
a bool argument type where previous an int was allowed). This
|
||||||
|
change should not pose additional problems and is not specified in
|
||||||
|
detail by this PEP.
|
||||||
|
|
||||||
|
|
||||||
|
Clarification
|
||||||
|
|
||||||
|
This PEP does *not* change the fact that almost all object types
|
||||||
|
can be used as truth values. For example, when used in an if
|
||||||
|
statement, an empty list is false and a non-empty one is true;
|
||||||
|
this does not change and there is no plan to ever change this.
|
||||||
|
|
||||||
|
The only thing that changes is the preferred values to represent
|
||||||
|
truth values when returned or assigned explicitly. Previously,
|
||||||
|
these preferred truth values were 0 and 1; the PEP changes the
|
||||||
|
preferred values to False and True, and changes built-in
|
||||||
|
operations to return these preferred values.
|
||||||
|
|
||||||
|
|
||||||
Compatibility
|
Compatibility
|
||||||
|
@ -244,12 +323,12 @@ Issues
|
||||||
for every x that is considered true in a Boolean context, the
|
for every x that is considered true in a Boolean context, the
|
||||||
expression x == True should be true, and likewise if x is
|
expression x == True should be true, and likewise if x is
|
||||||
considered false, x == False should be true. This is of course
|
considered false, x == False should be true. This is of course
|
||||||
impossible; it would mean that e.g. 6 == True and 7 == True, from
|
impossible; it would mean that for example 6 == True and 7 ==
|
||||||
which one could infer 6 == 7. Similarly, [] == False == None
|
True, from which one could infer 6 == 7. Similarly, [] == False
|
||||||
would be true, and one could infer [] == None, which is not the
|
== None would be true, and one could infer [] == None, which is
|
||||||
case. I'm not sure where this suggestion came from; it was made
|
not the case. I'm not sure where this suggestion came from; it
|
||||||
several times during the first review period. For truth testing
|
was made several times during the first review period. For truth
|
||||||
of a value, one should use "if", e.g. "if x: print 'Yes'", not
|
testing, one should use "if", as in "if x: print 'Yes'", not
|
||||||
comparison to a truth value; "if x == True: print 'Yes'" is not
|
comparison to a truth value; "if x == True: print 'Yes'" is not
|
||||||
only wrong, it is also strangely redundant.
|
only wrong, it is also strangely redundant.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue