PEP 285: Adding a bool type: yes, but not as int subtype

Ype Kingma ykingma at accessforall.nl
Sat Mar 30 16:23:54 EST 2002


Guido,

you wrote:
> 
> I offer the following PEP for review by the community.  If it receives
> a favorable response, it will be implemented in Python 2.3.
> 

Thanks for this opportunity.

>     http://python.org/sf/528022
> 
> --Guido van Rossum (home page: http://www.python.org/~guido/)
> 
> PEP: 285
> Title: Adding a bool type
> Version: $Revision: 1.12 $
> Last-Modified: $Date: 2002/03/30 05:37:02 $
> Author: guido at python.org (Guido van Rossum)
> Status: Draft
> Type: Standards Track
> Created: 8-Mar-2002
> Python-Version: 2.3
> Post-History: 8-Mar-2002, 30-Mar-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
> 
>     Dear reviewers:
> 
>     I'm particularly interested in hearing your opinion about the
>     following three issues:
> 
>     1) Should this PEP be accepted at all.

Partially.


I think there is no point in maintaining backward compatibility
of the assumptions that True == 1 and False == 0.
Please don't subtype int to define bool.

Within the language a 'cast to boolean' should be implied when a boolean
value is expected (ie. after 'if' and 'while'). This is in line with 
the current situation. Making this cast to boolean explicit in the language
definition even simplifies the language definition.

> 
>     2) Should str(True) return "True" or "1": "1" might reduce
>        backwards compatibility problems, but looks strange to me.
>        (repr(True) would always return "True".)
> 

str(True) should return "True".

>     3) Should the constants be called 'True' and 'False'
>        (corresponding to None) or 'true' and 'false' (as in C++, Java
>        and C99).
> 

Caps.

>     Most other details of the proposal are pretty much forced by the
>     backwards compatibility requirement; e.g. True == 1 and
>     True+1 == 2 must hold, else reams of existing code would break.
> 

This can be handled by deprecation and eg. 'from __future__ import bool',
or by unundeprecation: 'from __past__ import nonbool'.

This might seem rather radical, but in C a similar thing has happened:
the compiler would silently cast a C int to a C pointer in earlier
versions of the language. Nowadays no C programmer would even dare
to think that way.

>     Minor additional issues:
> 
>     4) Should we strive to eliminate non-Boolean operations on bools
>        in the future, through suitable warnings, so that e.g. True+1
>        would eventually (e.g. in Python 3000 be illegal).  Personally,
>        I think we shouldn't; 28+isleap(y) seems totally reasonable to
>        me.
> 

28+isleap(y) might seem reasonable now, but one should hope/assume that
Python outlives C at which point it will/would be just ballast.

Some other arguments against 28+isleap(y):
- explicit 28+int(isleap(y)) is better than implicit.
- here isleap should have been called onewhenleap in the first place.
- a current boolean function might return eg. a non empty list or an Ellipsis
  to indicate a True return value, resulting in an appropriate TypeError here.

A bool is a bool and an int is an int.
The only relation between them is that they have to be implemented using
bits of a computer.
Python is sufficiently high level not to care about the bits.
Python never had a C float type, only a C double type, for precisily
this reason.

Somehow this reminds me of subclassing Square from Rectangle:
it just doesn't feel right, even though it might work.
One should avoid subclassing a class that has instantiations.
Could someone provide a reference for this with a title
that ends in 'considered harmful'?


>     5) Should operator.truth(x) return an int or a bool.  Tim Peters
>        believes it should return an int because it's been documented
>        as such.  I think it should return a bool; most other standard
>        predicates (e.g. issubtype()) have also been documented as
>        returning 0 or 1, and it's obvious that we want to change those
>        to return a bool.
> 

Predicates should return a bool.

> 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.
> 

That would be nice. Currently in jython one has to use java.lang.Bool
to call an overloaded java method that is defined with both a java boolean
and with a java int as argument. This does not happen too often,
but mapping a python bool to (and from) a java bool sure sounds good.

>     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.  Writing bool(x) is much clearer than "not not x"
>     and much more concise than
> 
>         if x:
>             return 1
>         else:
>             return 0
> 
That would be great, however such functions should not be named as predicates,
they should be named onewhen...

<snip>

> 
> 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.
> 

The only reason that it works now is the C heritage as explained above.
Why not use this as an opportunity to get rid of it?

With a non int bool, True and False would be real singletons:

bool(1) is True
bool(0) is False

True is not 1
True != 1
False is not 0
False != 0


Subclassing bool from int would also force 1 and 0 to be become
real singletons. The only reason this would work is that current
python implementations happen to implement 1 and 0 in this way.
This is related to subclassing an instantiated class, which should
be avoided, I think.

>     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.

But you could make the language definition simpler by
explicitly defining the cast to bool in contexts where a boolean is expected,
see above. This would allow the current casts (eg. list to bool as non empty)
to be described at the standard types instead of in the language definition.

>     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)".

These would work in the same way with a "non int" bool as I would prefer to have.

<snip>

Regards, and thanks again for the opportunity,

Ype.



More information about the Python-list mailing list