Operator Precedence/Boolean Logic
steve at pearwood.info
Wed Jun 29 09:08:01 EDT 2016
On Wed, 29 Jun 2016 08:21 pm, Rustom Mody wrote:
> So if we are in a link-pillow-fight here is a link
> in which python-dev Nick Coghlan answers the question:
>> Q: ...supporting arithmetical operations (1+True==2) was a primary
>> intention, in which case my question is "why?".
>> Nick: The inheritance from int meant the default behaviour was to support
>> type-promoting integer arithmetic operations in addition to bitwise
>> That changes the question from "Why support that?" to "Why do the extra
>> design, documentation and implementation work needed to prevent that?".
>> The fact that "1 + True == 2" is surprising hasn't proven to be enough to
>> motivate anyone to define the precise subset of operations they want to
>> prevent, and then make the case for those restrictions as Python's native
Nick is a very senior core developer, and we would be foolish to ignore his
opinion, but that doesn't make his comments gospel.
To Nick, having 1+True return 2 is an accident of implementation, where it
is too much work to prevent it for the minimal gain it would give. And
historically, that was Guido's attitude back when Python gained a bool
(Initially Python gained to pseudo-constants, True and False, set equal to 1
and 0; then in the following release it gained a built-in type bool that
subclassed int, with exactly two instances, True and False.)
But it is my argument that with (roughly) ten years of experience with us,
we can say that 1+True == 2 is not just an unfortunate accident of
implementation that we are forced to live with because nobody wants to do
the work to correct it. Rather, it is a useful and desirable feature. If I
were designing a new language from scratch, I would probably follow
Python's lead and use an int subclass for bools.
As I said before, this isn't to dispute or deny the fact that bools-as-ints
have unfortunate consequences. But they have useful consequences too, and
in my opinion they outweigh the bad ones.
If you disagree, okay, you disagree. I like broccoli and hate streaky bacon,
others feel the opposite way. I'm lucky that Python, due to historical
accident, ended up working the way I prefer. When you design your own
language, you can make it work the way you prefer.
> More significant...
> Steven D'Aprano wrote:
>> So we have falsey values:
Note that the question of truthy/falsey duck-typed bools is independent of
whether bools are abstract flags or concrete ints. A language could:
- have a dedicated, abstract bool type, like Pascal does;
- completely do without a dedicated bool type, and just have truthy/falsey
values, like Python 1.5 did;
- allow all values to be treated as truthy/falsey values, but have a
concrete (int-subclass) bool type as the canonical true/false, like Python
2 & 3 does;
- allow all values to be treated as truthy/falsey values, but have an
So the question of truthy/falsey values is orthogonal to the question of
whether bool should inherit from int.
> In short,
> - Steven hints that empty/non-empty is some sort of *generic* property of
> data structures - Chris strengthens that to include types outside of
> builtins -- Red-Black trees - Marko (thankfully adding the I dont like)
> connects emptiness to the dunder __bool__
It's not just a hint. Python has a convention that empty collections should
be treated as falsey; likewise empty sequences; likewise "empty" numbers.
And non-empty ones should be treated as truthy. This is built into the way
the interpreter decides whether something is truthy or falsey.
if spam: ...
Python decides which branch to take as follows:
- if spam has a __len__ method, and spam.__len__() returns 0, then spam is
falsey and the `else` branch is taken;
- if spam.__len__() returns a non-zero number, then spam is truthy and the
`if` branch is taken;
- otherwise, if spam has a __nonzero__ method (__bool__ in Python 3), if it
returns a falsey value, then spam is falsey;
- but if it returns a truthy value, then spam is truthy;
- and if spam has neither a __len__ nor a __nonzero__ / __bool__ method,
then by default it is truthy.
> So here's some questions for the bool-fans
> Please show me how we would define __bool__ for
> 1. Graphs -- the kind mathematicians define with "Let G =(V,E) be a
I would make the empty graph (zero nodes) falsey, and non-empty graphs (one
or more nodes) truthy.
> 2. Automata which in a way are special kinds of graphs
> 3. Regular Expressions which mathematically are related to automata
> And pragmatically are (more) present in python than the first two
Can you even have an empty regular expression? What does it match? Possibly
nothing at all.
Ideally, I would have the empty regular expression be falsey, and all others
truthy, but I wouldn't be too upset if all regexes were True.
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list