PEP 285: Adding a bool type

Alex Martelli aleax at aleax.it
Mon Apr 1 03:52:30 EST 2002


Guido van Rossum wrote:
        ...
>     I'm particularly interested in hearing your opinion about the
>     following three issues:
> 
>     1) Should this PEP be accepted at all.

No, -1, please don't.  It seems to me that the advantages are small:

a. We don't have to model _every_ important concept with a type.  A
_protocol_, yes, but we do already have a Truth 'protocol' just as we
have (say) an Iterator one without needing an Iterator _type_.

b. The hoped-for uniformity of notation won't happen -- we've already 
seen on these threads people who want every constant to be uppercased
(to make it 'stand out') and so will use TRUE=True etc anyway.

c. The ability to model Booleans separately from integers when interfacing
external stuff (databases, rpc systems, etc) cuts both ways -- we may be a 
little better placed regarding external systems that do draw this 
"distinction without a difference" (although it seems to me that we're
doing fine already), we'll be a little worse placed regarding external 
systems that don't (such as, we're told, MySql) -- and the transition
costs will, I think, balance out and nullify any hoped-for gain.

d. Other languages have (in some cases) their own reasons to introduce
boolean types -- e.g., in C++, the ability to define an 'operator bool' that
is distinguished from 'operator int' (although this hoped-for gain did NOT
in practice materialize due to the transparent bool->int conversion...) --
but in Python we already have __int__ and __nonzero__ specials (and we
hear the latter is not due for renaming anyway) so, no advantage here; in
Java, the need to diagnose errors for such constructs as 'if(x=0)' -- but
in Python, we already forbid that, so, no advantage here; and so on.

e. normalization to 0 or 1 might better be accomplished by making
operator.truth better known (we've heard about its introducer, Jim Fulton,
having forgotten about its existence and still pining for it) and more
available, e.g. by hoisting it up to builtins (name it bool or name it truth
or whatever, but have it always available) -- a minimal change that has
some small but real benefits at very small cost (for compatibility I guess
operator.truth would stay available, just like module exceptions stays
around even though exception classes are built-ins).

f. the claimed conceptual benefits in easing the lives of programmers and
newbies in particular I consider as illusions.  Programmers want booleans
iff they're used to them from previous languages -- I've never seen people
used to (e.g.) APL, good old (uncommon?-) Lisp, or (dare I say it) Perl,
feel sad and deprived by the lack of booleans in their respective languages.
I _have_ seen old-time Fortranites rant quite convincingly against that
useless, newfangled LOGICAL stuff.  And since we can't spell the type in
every way at once, we're not going to soothe all unjustified desires due to
previous habits anyway -- if it's bool the Javaites will pine for boolean, 
and viceversa, and those Fortranites (if any) who've come to love their
LOGICAL's won't find them anyway.  Just as the constants won't be
spelled 'True' AND 'true' AND 'TRUE' and (particularly:-) '.TRUE.' too...

Newbies in my teaching experience grok 0/1 at once.  Look at the on/off
switch of many modern appliances and what do you see there?  0 for off,
1 for on.  I think it's even some kind of international standard, but in any
case there IS a lot of precedent for it and I've gotten perfect mileage by
using it in teaching.  Many fewer people have heard of George Boole than
have used appliances with 0 and 1 on their switches.  _Particularly_ since,
by this PEP, we're going to keep using False and True for arithmetic, with
them being equal to 0 and 1 respectively for all matters arithmetic, giving
them this dual identity and dual names won't help beginners at all.

Which leads me right onto disadvantages of the PEP -- because that's
the main one I see: extra conceptual load in teaching the language.  "0 can
be spelled either 0 or False" with subtly (but generally irrelevantly:-) 
different consequences... _please_ don't force me to have to teach that.
I'm not a staunch paladin of Python's simplicity when that simplicity has
substantial costs -- I fully agree that practicality beats purity and all 
that -- but simplicity IS still an important Pythonic value.  Diminishing 
that simplicity by a little bit for no substantial benefit would seem a 
wrong decision to me -- and I've already argued, I hope, that the benefits
we expect from this change _are_ insubstantial... "pretty small" at best.
When in doubt, I'd pump for choosing simplicity and stability.  Not that I'm
really in doubt here (I dislike this bool introduction:-) but even if I 
were I'd use the simplicity criterion to decide:-).

I've wasted too much of my life trying to explain to people why they must
NOT code "if some_condition==True:" or the equivalent thereof in various
languages, but just "if some_condition:".  The "== True" appendix, useless
at best, often damaging, seems one of the most natural errors by newbies.
In Python I was blessedly spared that waste of teaching time.  If the PEP
is approved, I'll be back to wasting that time and effort (perhaps more,
given how seductive "is True" will appear to many newbies...!).

Breakage will be modest but will be there, in doctest usage and other
kinds of tests -- wherever some output is compared with some expected
output, I'll get false errors over and over again depending on what choice
is made for str and repr.  Unless str and repr are both '0' and '1'.  If 
they are, the point of the PEP becomes murkier.  And what happens to
other forms of output, such as marshaling and pickling -- does the bool
or int nature of a 0 or 1 get preserved or lost in a round trip?  I can see
disadvantages and breakage possibilities in either case.

There are other minor issues too, such as the breakage of (already
rather broken) legacy code that typetests with type(a)==type(0), or
type(a)==types.IntType; and the likely bickering on c.l.p about being
able to do True*6 &c, which I fear will be more substantial than the
very occasional bleating about "not having booleans"; but these _are_
admittedly minor.  Still, the overall balance seems negative to me.

It won't break Python if you pass this PEP.  It will, however, make it
a little bit worse, IMHO -- and just when I was hoping we'd see one
release without substantial changes to the core language, which I
think would have been a nice public-relations plus with those circles
that are worried about language stability.  Oh well.


If this change does go ahead, here's my opinion on the sub-issues:


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

Breakage would be a little bit less with '1'.  Yes, it does look
strange -- but so does the whole PEP, to me:-).  If you hadn't
posted it weeks ago to python-dev one might be inclined to suspect 
an April Fool's joke...:-).

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

Uppercasing seems preferable here.

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

Yes.  We can't have "real" booleans (a la Pascal/Java) -- thanks be.

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

I agree with you.  "real" booleans (on which one cannot do arithmetic)
basically just force insertion of a lot of extra int() calls and do nothing
but reduce readability thereby.

>     5) Should operator.truth(x) return an int or a bool.  Tim Peters

An int.  There are other ways to get a bool: why make operator.truth
identical with the proposed bool builtin?  Better to have a direct way
to get an int 0 or 1 and one to get a bool, than two ways to get a
bool and nothing but multiple ops (int(bool(blah))) to get an int.

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

If this PEP passes, docs and functions throughout the library will
indeed have to be changed (not a point in its favor:-).  But there
are substantial reasons to keep operator.truth unchanged (give a
direct way to get 0/1) and none that I can see to have it become a
useless duplicate of the new bool builtin.


Alex




More information about the Python-list mailing list