bool behavior in Python 3000?

T

Terry Reedy

| I think that the assignability to the names 'True' and 'False' is
| incorrect, or at the very least subject to all sorts of odd results.

It is necessary for 2.x to not break older code. I believe they will
somehow be reserved, like None, in 3.0.

tjr
 
S

Steve Holden

Terry said:
| I think that the assignability to the names 'True' and 'False' is
| incorrect, or at the very least subject to all sorts of odd results.

It is necessary for 2.x to not break older code. I believe they will
somehow be reserved, like None, in 3.0.
But of course None was assignable until (?) 2.3 and then became formally
constant, so it was no longer possible to assign to it or even shadow it
in a local namespace. So much for that kind of backward compatibility!

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
T

Terry Reedy

In reply to various current discussants: there was a long discussion here
(clp) of similar points of view when bool was introduced. In Guido's
opinion (and mine, but his counts 100x), the positive benefits of the
current implementation are greater than the net positive benefits of a
'pure' type. See

http://www.python.org/dev/peps/pep-0285/


tjr
 
S

Steven D'Aprano

No, I think Bjoern just wanted to point out that all those binary
boolean operators already work *perfectly*. You just have to emphasize
that you're doing boolean algebra there, using `bool()`.
"Explicit is better than implicit."


So we should always write things explicitly like:

if bool(bool(some_condition) is True) is True:
first_line = str(some_string).split(str("\n"))[int(0)]
n = int(int(len(list(some_list))) + int(1))
elif bool(bool(some_condition) is False) is True:
f = float(math.sin(float(6.0)/float(math.pi)))

instead of the less explicit code. I'll try to remember that, thank you
for the advice.
 
P

Paul Rubin

Steve Holden said:
But of course None was assignable until (?) 2.3 and then became
formally constant, so it was no longer possible to assign to it or
even shadow it in a local namespace. So much for that kind of backward
compatibility!

None was present in the language for a long time before 2.3 though,
and any code that actually assigned to it was asking for trouble.
True and False didn't exist til recently and it was common for
programs to define them.
 
S

Steven D'Aprano

But `bools` are usefull in some contexts.


Agreed. Syntactic sugar is useful, even though it is unnecessary. I'm not
against having bools. I just want them to be Booleans, not dicts, or
lists, or sets, or even integers.
 
S

Steven D'Aprano

Remember that while Python 3 is allowed to break backwards
compatibility, it's only supposed to do it when there are concrete
benefits. Clearly there are existing use cases for treating bools like
ints, e.g. from Alexander Schmolck's email:

(x < b) * f(x)
-1 ** (i == j)

You have cause and effect confused here. Expressions like (i == j) used
to return 0 and 1, and it was to avoid breaking hacks like the above
that bools were implemented as a subclass of int, not because being
able to write the above was a specific feature requested.

In the hypothetical bright new world of Python with bools that are
actually bools, the above are good cases for explicit being better than
implicit:

int(x < b) * f(x)
-1 ** int(i == j)

It makes more sense to explicitly cast bools to ints when you want to
do integer arithmetic on them, rather than explicitly casting bools to
bools to do boolean arithmetic! I feel strongly enough about this that I
believe that being able to write (x < b) * f(x) is a DISADVANTAGE -- it
gives me a real WTF moment to look at the code.

In some hypothetical world where backwards compatibility was not an
issue, where bools had already existed, if somebody had specifically asked
for bools to become ints so they could write (x < b) * f(x), I have every
confidence that their request would have been denied, and they would have
been told to explicitly cast the bool to an int. As they should.
 
T

tah

If you want to do algebra with bools in python then use the logical
operators (and or not) and not the arithmetical operators.

Eg

False

Let me comment on what I suspect is Alan's Hidden Agenda (tm). Since
this question surfaced earlier on the numpy list, I suspect that part
of the motivation here has to do with trying to come up with a natural
way to work with arrays of booleans. The operators and,or,not don't
work for this purpose since they can't be overloaded to return an
arbitrary value. You can almost make this work with &,|,^:
a = np.array([True, False, False])
b = np.array([True, True, False])
a & b array([ True, False, False], dtype=bool)
a | b array([ True, True, False], dtype=bool)
a ^ b
array([False, True, False], dtype=bool)

This is meshes well with the behavior of True and False:
False

This doesn't leave you with anything equivalent to 'not' however. Or
nothing consistent. Currently '~a' will complement a boolean array,:
array([False, True, True], dtype=bool)

However that's less than ideal since it doesn't mesh up with the
behavior of booleans on their own:
-2

That's potentially confusing. It's not any skin of my nose since I
use, and will likely continue to use, boolean arrays in only the most
rudimentary ways. However, I thought I'd offer some additional
context.

-tim
 
P

Paul Rubin

tah said:
This doesn't leave you with anything equivalent to 'not' however. Or
nothing consistent. Currently '~a' will complement a boolean array,:
array([False, True, True], dtype=bool)

Can you use operator.not_(a) ?
 
S

Stargaming

Steven said:
No, I think Bjoern just wanted to point out that all those binary
boolean operators already work *perfectly*. You just have to emphasize
that you're doing boolean algebra there, using `bool()`.
"Explicit is better than implicit."



So we should always write things explicitly like:

if bool(bool(some_condition) is True) is True:
first_line = str(some_string).split(str("\n"))[int(0)]
n = int(int(len(list(some_list))) + int(1))
elif bool(bool(some_condition) is False) is True:
f = float(math.sin(float(6.0)/float(math.pi)))

instead of the less explicit code. I'll try to remember that, thank you
for the advice.

You're missing like 400 bool(...) is True constructs there! Fatal error,
recursion depth reached. Aww!
 
?

=?ISO-8859-15?Q?Nis_J=F8rgensen?=

Alan Isaac skrev:
Since it is seemingly ignored in most of the comments
on this thread, I just want to remind that PEP 285
http://www.python.org/dev/peps/pep-0285/
says this:

In an ideal world, bool might be better implemented as a
separate integer type that knows how to perform mixed-mode
arithmetic.

I mentioned Python 3000 since that is an opportunity for an ideal world.

You forgot to quote this bit:

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.

Nis
 
B

Ben Finney

Terry Reedy said:
In Guido's opinion (and mine, but his counts 100x), the positive
benefits of the current implementation are greater than the net
positive benefits of a 'pure' type. See

http://www.python.org/dev/peps/pep-0285/

I assume you're referring to:

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 [...further explanation...]

I accept Guido's explanation in the PEP, that the implementation is
made much easier, as an explanation of why bool inherits from int. I
haven't seen people here expressing that they want the opposite.

To my mind the more fundamental issue is this one:

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.

Frustratingly, unlike the above point about inheritance, the PEP gives
no explanation of why the answer to this is "No". All we get is "most
reviewers agree", with no explanation of *why*.

So, I'm left with the points already made in this thread as to why the
answer should be "yes", and no source online for an official
explanation of the "no".
 
B

Bjoern Schliessmann

Alan said:
Bjoern Schliessmann wrote:
<type 'bool'>

Thanks anyway, but I remembered it shortly after sending. Thus the
cancel (seems to have failed a bit).

Regards,


Björn
 
B

Bjoern Schliessmann

Steven said:
It seems to me that you deliberately misunderstood him.

I know for sure I didn't.
Why else would you type-cast the integers 2 and 1 to bools to
supposedly demonstrate that there's nothing wrong with operations
between bools returning ints?

Kindly excuse me bothering You.


Björn
 
A

Alexander Schmolck

Steven D'Aprano said:
Expressions like (i == j) used to return 0 and 1, and it was to avoid
breaking hacks like the above that bools were implemented as a subclass of
int, not because being able to write the above was a specific feature
requested. In the hypothetical bright new world of Python with bools that
are actually bools, the above are good cases for explicit being better than
implicit:

int(x < b) * f(x)
-1 ** int(i == j)

It makes more sense to explicitly cast bools to ints when you want to
do integer arithmetic on them, rather than explicitly casting bools to
bools to do boolean arithmetic! I feel strongly enough about this that I
believe that being able to write (x < b) * f(x) is a DISADVANTAGE -- it
gives me a real WTF moment to look at the code.

Just because it looks funny to you doesn't mean it is a hack. It turns out
that many mathemtical formulas can be written more clearly using this notation
(see e.g. at knuth et al's "concrete mathematics"), and in mathematics limited
and often ambiguous ad hoc notation that is neatly subsumed by this scheme is
widely established.

And I don't think adding int is an improvement: ``(x < b) * f(x)`` is plenty
clear (not easily misread as something else and, I believe, not even
particularly difficult to figure out even for mediocre python programmers) but
adding padding just obscures formula structure. Of course it doesn't in the
above examples with less than half a dozen terms, but IMO for something longer
the int-litter, even it may be soothing the psyches of the anally retentive,
is counterproductive.

'as
 
A

Alan Isaac

Alan Isaac skrev:
You forgot to quote this bit: [4)]


Actually not. That is a different point.
Ben seems bothered by this, but not me.
I do not mind that True+1 is 2.
I won't do it, but I do not object to it
being possible.

I do not like that True+True is 2.
I do not like that bool(False-True) is True.
I do not like that True and False are assignable,
which clearly begs for bugs to pass unseen.
False True

Who can like that????

I also generally agree with Steve, whose points
keep being twisted beyond recognition.

Also, tah is right about my underlying interest
in arrays of bools (and more specifically,
boolean matrices).

I think Python 3000 is the right time to reconsider
the "ideal world" that Guido mentions in PEP 285.

Cheers,
Alan Isaac
 
M

Miles

I do not like that bool(False-True) is True.

I've never seen the "A-B" used to represent "A and not B", nor have I
seen any other operator used for that purpose in boolean algebra,
though my experience is limited. Where have you seen it used?

What's wrong with 'and', 'or', and 'not'? I think that redefining *,
+, and - to return booleans would only encourage programmers to use
them as shortcuts for standard boolean operations--I'd hate to see
code like this:
I don't mind that arithmatic operations are _possible_ with bools, but
I would strongly prefer to see the boolean keywords used for
operations on booleans.

-Miles
 
B

Bruno Desthuilliers

Steven D'Aprano a écrit :
(snip)
It makes more sense to explicitly cast bools to ints

s/cast bools to ints/build ints from bools/

AFAICT, there's no such thing as typecast in Python.
 
B

Bruno Desthuilliers

Miles a écrit :
I've never seen the "A-B" used to represent "A and not B", nor have I
seen any other operator used for that purpose in boolean algebra,
though my experience is limited. Where have you seen it used?

I've personnaly seen the usual arithmatic operators used for boolean
algebra in quite a lot of papers covering the topic - but I've always
had to translate them to more common boolean ops to understand these
papers.
What's wrong with 'and', 'or', and 'not'? I think that redefining *,
+, and - to return booleans would only encourage programmers to use
them as shortcuts for standard boolean operations--I'd hate to see
code like this:

OMG ! Lord have mercy ! St Guido, save us !
I don't mind that arithmatic operations are _possible_ with bools, but
I would strongly prefer to see the boolean keywords used for
operations on booleans.

+10
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top