Steven D'Aprano writes:
On Thu, Apr 07, 2016 at 11:08:38AM -0700, Guido van Rossum wrote:
To be more precise, there are some "arithmetic" operations (+, -, *, /, **) and they all treat bools as ints and always return ints; there are also some "bitwise" operations (&, |, ^, ~) and they should all treat bools as bools and return a bool.
I'm with Steven on this. Knuth would call these operations "seminumerical". I would put the emphasis on "numerical", *expecting* True and False to be one-bit representations of the (mathematical) integers 1 and 0. If numerical operations widen bools to int and then operate, I would *expect* seminumerical operations to do so as well. In fact, I was startled by Antoine's post. I even have a couple of lines of code using "^" as a *logical* operator on known bools, carefully labeled "# Hack! works only on true bools." That said, I'm not Dutch, and if treating bool as "not actually int" here is the right thing to do, then I would think the easiest thing to do would be to interpret the bitwise operations as performed on (mythical) C "itty-bitty ints".[1] Then ~ does the right thing and True << 1 == True >> 1 == False << 1 == False >> 1 == 0 giving us four new ways to spell 0 as a bonus!
After all, not withstanding their fancy string representation,
I guess "fancy string representation" was the original motivation for the overrides. If the intent was really to make operator versions of logical operators (but only for true bools!), they would have fixed ~ too.
they behave like ints and actually are ints.
I can't fellow-travel all the way to "actually are", though. bools are what we decide to make them. I just don't see why the current behaviors of &|^ are particularly useful, since you'll have to guard all bitwise expressions against non-bool truthies and falsies. Footnotes: [1] "itty-bitty" almost reads "1 bit" in Japanese!