ACCEPTED: PEP 285
djw
dwelch91 at nospam.attbi.com
Wed Apr 3 20:50:13 EST 2002
Pardon my ignorance (I've only been working with Python for a short
while), but I don't understand why an idiom like:
if x == True:
would be/should be an error (or warning initially). I see C/C++ code
like this all the time:
bool x;
x = Foo(Bar);
if (x==true)
{...
Of course, this could also be written in the more abbreviated form as
well. But, why force that on the programmer? I really prefer the more
explicit comparison of x with true rather than the if(x) idiom. Myself,
being a newbie Python programmer (but not a newbie programmer in C, C++,
etc), I would find it somewhat confusing that I could not compare a
variable to a valid value for the variable using what appears to be a
valid operator.
Am I missing something more subtle here?
Just curious, sorry for the interruption.
Don
Guido van Rossum wrote:
> Here's one final posting of PEP 285. I've read (or at least skimmed)
> all feedback that was on our news server by 9:30am EST on April 2nd,
> plus anything mailed directly to me or to python-dev until now.
>
> There was a lot of negative feedback, but there was also a lot of
> support for the PEP. The feedback made it easy to decide on most of
> the smaller issues in the review section of the PEP as previously
> posted: even reviewers who were against the PEP mostly supported my
> preferences for the various details.
>
> Despite the negative feedback, I've decided to accept the PEP. The
> most important perceived problem is that newbies tend to write
>
> if x == True: ...
>
> where they should write
>
> if x: ...
>
> I believe this problem should be solved by education (the Zen master
> hits the student on the head with a stick, and the student gets
> enlightenment) rather than by holding back what I believe will be a
> useful feature. You can expect the bool type in Python 2.3; it will
> be in CVS tonight.
>
> --Guido van Rossum (home page: http://www.python.org/~guido/)
>
> PEP: 285
> Title: Adding a bool type
> Version: $Revision: 1.20 $
> Last-Modified: $Date: 2002/04/03 22:11:05 $
> Author: guido at python.org (Guido van Rossum)
> Status: Accepted
> Type: Standards Track
> Created: 8-Mar-2002
> Python-Version: 2.3
> Post-History: 8-Mar-2002, 30-Mar-2002, 3-Apr-2002
>
>
> Abstract
>
> This PEP proposes the introduction of a new built-in type, bool,
> with two constants, False and True. The bool type would be a
> straightforward subtype (in C) of the int type, and the values
> False and True would behave like 0 and 1 in most respects (for
> example, False==0 and True==1 would be true) except repr() and
> str(). All built-in operations that conceptually return a Boolean
> result will be changed to return False or True instead of 0 or 1;
> for example, comparisons, the "not" operator, and predicates like
> isinstance().
>
>
> Review
>
> I've collected enough feedback to last me a lifetime, so I declare
> the review period officially OVER. I had Chinese food today; my
> fortune cookie said "Strong and bitter words indicate a weak
> cause." It reminded me of some of the posts against this
> PEP... :-)
>
> Anyway, here are my BDFL pronouncements. (Executive summary: I'm
> not changing a thing; all variants are rejected.)
>
> 1) Should this PEP be accepted?
>
> => Yes.
>
> There have been many arguments against the PEP. Many of them
> were based on misunderstandings. I've tried to clarify some of
> the most common misunderstandings below in the main text of the
> PEP. The only issue that weighs at all for me is the tendency
> of newbies to write "if x == True" where "if x" would suffice.
> More about that below too. I think this is not a sufficient
> reason to reject the PEP.
>
> 2) Should str(True) return "True" or "1"? "1" might reduce
> backwards compatibility problems, but looks strange.
> (repr(True) would always return "True".)
>
> => "True".
>
> Almost all reviewers agree with this.
>
> 3) Should the constants be called 'True' and 'False' (similar to
> None) or 'true' and 'false' (as in C++, Java and C99)?
>
> => True and False.
>
> Most reviewers agree that consistency within Python is more
> important than consistency with other languages.
>
> 4) Should we strive to eliminate non-Boolean operations on bools
> in the future, through suitable warnings, so that for example
> True+1 would eventually (in Python 3000) be illegal?
>
> => No.
>
> There's a small but vocal minority that would prefer to see
> "textbook" bools that don't support arithmetic operations at
> all, but most reviewers agree with me that bools should always
> allow arithmetic operations.
>
> 5) Should operator.truth(x) return an int or a bool?
>
> => bool.
>
> Tim Peters believes it should return an int, but almost all
> other reviewers agree that it should return a bool. My
> rationale: 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. (Under the PEP,
> operator.truth() now becomes an alias for bool(); that's fine.)
>
> 6) Should bool inherit from int?
>
> => Yes.
>
> 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 this is right in terms of
> substitutability: 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?
>
> => No.
>
> Some reviewers have argued 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. To a newbie,
> it doesn't matter whether it's called a waffle or a bool; it's
> a new word, and they learn quickly what it means.
>
> One reviewer has argued 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."
>
> 8) Should we strive to require that Boolean operations (like "if",
> "and", "not") have a bool as an argument in the future, so that
> for example "if []:" would become illegal and would have to be
> writen as "if bool([]):" ???
>
> => No!!!
>
> Some people believe that this is how a language with a textbook
> Boolean type should behave. Because it was brought up, others
> have worried that I might agree with this position. Let me
> make my position on this quite clear. This is not part of the
> PEP's motivation and I don't intend to make this change. (See
> also the section "Clarification" below.)
>
>
> Rationale
>
> Most languages eventually grow a Boolean type; even C99 (the new
> and improved C standard, not yet widely adopted) has one.
>
> Many programmers apparently feel the need for a Boolean type; most
> Python documentation contains a bit of an apology for the absence
> of a Boolean type. I've seen lots of modules that defined
> constants "False=0" and "True=1" (or similar) at the top and used
> those. The problem with this is that everybody does it
> differently. For example, should you use "FALSE", "false",
> "False", "F" or even "f"? And should false be the value zero or
> None, or perhaps a truth value of a different type that will print
> as "true" or "false"? Adding a standard bool type to the language
> resolves those issues.
>
> Some external libraries (like databases and RPC packages) need to
> be able to distinguish between Boolean and integral values, and
> while it's usually possible to craft a solution, it would be
> 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 same is
> apparently the case for some COM interfaces.)
>
> 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
> Boolean values. When a Boolean value needs to be normalized to
> one of two values, bool(x) is much clearer than "not not x" and
> much more concise than
>
> if x:
> return 1
> else:
> return 0
>
> Here are some arguments derived from teaching Python. When
> showing people comparison operators etc. in the interactive shell,
> I think this is a bit ugly:
>
> >>> a = 13
> >>> b = 12
> >>> a > b
> 1
> >>>
>
> If this was:
>
> >>> a > b
> True
> >>>
>
> it would require a millisecond less thinking each time a 0 or 1
> was printed.
>
> There's also the issue (which I've seen baffling even experienced
> Pythonistas who had been away from the language for a while) that
> if you see:
>
> >>> cmp(a, b)
> 1
> >>> cmp(a, a)
> 0
> >>>
>
> you might be tempted to believe that cmp() also returned a truth
> value, whereas in reality it can return three different values
> (-1, 0, 1). If ints were not (normally) used to represent
> Booleans results, this would stand out much more clearly as
> something completely different.
>
>
> Specification
>
> The following Python code specifies most of the properties of the
> new type:
>
> class bool(int):
>
> def __new__(cls, val=0):
> # This constructor always returns an existing instance
> if val:
> return True
> else:
> return False
>
> def __repr__(self):
> if self:
> return "True"
> else:
> return "False"
>
> __str__ = __repr__
>
> def __and__(self, other):
> if isinstance(other, bool):
> return bool(int(self) & int(other))
> else:
> return int.__and__(self, other)
>
> __rand__ = __and__
>
> def __or__(self, other):
> if isinstance(other, bool):
> return bool(int(self) | int(other))
> else:
> return int.__or__(self, other)
>
> __ror__ = __or__
>
> def __xor__(self, other):
> if isinstance(other, bool):
> return bool(int(self) ^ int(other))
> else:
> return int.__xor__(self, other)
>
> __rxor__ = __xor__
>
> # Bootstrap truth values through sheer willpower
> False = int.__new__(bool, 0)
> True = int.__new__(bool, 1)
>
> The values False and True will be singletons, like None. Because
> the type has two values, perhaps these should be called
> "doubletons"? The real implementation will not allow other
> instances of bool to be created.
>
> True and False will properly round-trip through pickling and
> marshalling; for example pickle.loads(pickle.dumps(True)) will
> return True, and so will marshal.loads(marshal.dumps(True)).
>
> All built-in operations that are defined to return a Boolean
> result will be changed to return False or True instead of 0 or 1.
> In particular, this affects comparisons (<, <=, ==, !=, >, >=, is,
> is not, in, not in), the unary operator 'not', the built-in
> functions callable(), hasattr(), isinstance() and issubclass(),
> the dict method has_key(), the string and unicode methods
> endswith(), isalnum(), isalpha(), isdigit(), islower(), isspace(),
> istitle(), isupper(), and startswith(), the unicode methods
> isdecimal() and isnumeric(), and the 'closed' attribute of file
> objects. The predicates in the operator module are also changed
> to return a bool, including operator.truth().
>
> Because bool inherits from int, True+1 is valid and equals 2, and
> so on. This is important for backwards compatibility: because
> comparisons and so on currently return integer values, there's no
> way of telling what uses existing applications make of these
> 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.
>
>
> C API
>
> The header file "boolobject.h" defines the C API for the bool
> type. It is included by "Python.h" so there is no need to include
> it directly.
>
> The existing names Py_False and Py_True reference the unique bool
> objects False and True (previously these referenced static int
> objects with values 0 and 1, which were not unique amongst int
> values).
>
> A new API, PyObject *PyBool_FromLong(long), takes a C long int
> argument and returns a new reference to either Py_False (when the
> argument is zero) or Py_True (when it is nonzero).
>
> To check whether an object is a bool, the macro PyBool_Check() can
> be used.
>
> The type of bool instances is PyBoolObject *.
>
> The bool type object is available as PyBool_Type.
>
>
> 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
>
> Because of backwards compatibility, the bool type lacks many
> properties that some would like to see. For example, arithmetic
> operations with one or two bool arguments is allowed, treating
> False as 0 and True as 1. Also, a bool may be used as a sequence
> index.
>
> I don't see this as a problem, and I don't want evolve the
> language in this direction either. I don't believe that a
> stricter interpretation of "Booleanness" makes the language any
> clearer.
>
> Another consequence of the compatibility requirement is that the
> expression "True and 6" has the value 6, and similarly the
> expression "False or None" has the value None. The "and" and "or"
> operators are usefully defined to return the first argument that
> determines the outcome, and this won't change; in particular, they
> don't force the outcome to be a bool. Of course, if both
> arguments are bools, the outcome is always a bool. It can also
> easily be coerced into being a bool by writing for example "bool(x
> and y)".
>
>
> Resolved Issues
>
> (See also the Review section above.)
>
> - Because the repr() or str() of a bool value is different from an
> int value, some code (for example doctest-based unit tests, and
> possibly database code that relies on things like "%s" % truth)
> may fail. It is easy to work around this (without explicitly
> referencing the bool type), and it is expected that this only
> affects a very small amount of code that can easily be fixed.
>
> - Other languages (C99, C++, Java) name the constants "false" and
> "true", in all lowercase. For Python, I prefer to stick with
> the example set by the existing built-in constants, which all
> use CapitalizedWords: None, Ellipsis, NotImplemented (as well as
> all built-in exceptions). Python's built-in namespace uses all
> lowercase for functions and types only.
>
> - It has been suggested that, in order to satisfy user
> expectations, for every x that is considered true in a Boolean
> context, the expression x == True should be true, and likewise
> if x is considered false, x == False should be true. In
> particular newbies who have only just learned about Boolean
> variables are likely to write
>
> if x == True: ...
>
> instead of the correct form,
>
> if x: ...
>
> There seem to be strong psychological and linguistic reasons why
> many people are at first uncomfortable with the latter form, but
> I believe that the solution should be in education rather than
> in crippling the language. After all, == is general seen as a
> transitive operator, meaning that from a==b and b==c we can
> deduce a==c. But if any comparison to True were to report
> equality when the other operand was a true value of any type,
> atrocities like 6==True==7 would hold true, from which one could
> infer the falsehood 6==7. That's unacceptable. (In addition,
> it would break backwards compatibility. But even if it didn't,
> I'd still be against this, for the stated reasons.)
>
> Newbies should also be reminded that there's never a reason to
> write
>
> if bool(x): ...
>
> since the bool is implicit in the "if". Explicit is *not*
> better than implicit here, since the added verbiage impairs
> redability and there's no other interpretation possible. There
> is, however, sometimes a reason to write
>
> b = bool(x)
>
> This is useful when it is unattractive to keep a reference to an
> arbitrary object x, or when normalization is required for some
> other reason. It is also sometimes appropriate to write
>
> i = int(bool(x))
>
> which converts the bool to an int with the value 0 or 1. This
> conveys the intention to henceforth use the value as an int.
>
>
> Implementation
>
> A complete implementation in C has been uploaded to the
> SourceForge patch manager:
>
> http://python.org/sf/528022
>
> This will soon be checked into CVS for python 2.3a0.
>
>
> Copyright
>
> This document has been placed in the public domain.
>
>
>
> Local Variables:
> mode: indented-text
> indent-tabs-mode: nil
> fill-column: 70
> End:
>
>
More information about the Python-list
mailing list