[Python-ideas] Break the dominance of boolean values in boolean context
Terry Reedy
tjreedy at udel.edu
Tue Sep 13 00:27:15 CEST 2011
On 9/12/2011 4:20 PM, Lukas Lueg wrote:
> However the "or"-operator here grinds them
> both down to being just True or False.
Both 'and' and 'or' return one of their inputs unchanged and unground.
>>> a = 'a'
>>> b = 'b'
>>> a or b
'a'
>>> a and b
'b'
>>> c = ''
>>> a and c
''
>>> c and a
''
>>> a or c
'a'
>>> c or a
'a'
If both inputs are True or False, then or course you always get one of
them back. But again, no 'grind'ing.
> Why is it, that we can override the behaviour of
> arithmetic operations like "+, -, *, /", but not the boolean
> operations like "and, or, xor, not" ?
In Python, 'and' and 'or' are *not* (functional) boolean operations.
They are flow-control keywords that abbreviate in expression form an
if-else statement pattern. They are compiled to similar bytecode.
def f1(a,b):
return a and b
def f2(a,b):
if not a: return a
else: return b
from dis import dis
dis(f1)
dis(f2)
###
0 LOAD_FAST 0 (a)
3 JUMP_IF_FALSE_OR_POP 9
6 LOAD_FAST 1 (b)
9 RETURN_VALUE
0 LOAD_FAST 0 (a)
3 POP_JUMP_IF_TRUE 10
6 LOAD_FAST 0 (a)
9 RETURN_VALUE
10 LOAD_FAST 1 (b)
13 RETURN_VALUE
The difference is that the compiler does not notice that the 'a' to be
returned is the same 'a' that it just tested and which is still sitting
on the stack, so it reloads it or, if is were an expression, would
recalculate it. There is no internal function that *could* be
overloaded. In this sense, they are similar to 'lambda expressions,
which abbreviate a simple def statement pattern and which compile to
essentially the same bytecode as the def statement.
The xor bitwise int operator '^' can be overloaded: __xor__ and
__rxor__. Logical xor can be implemented as bool(a)^bool(b).
Before there was a bool class, 'not not a' was the direct way to coerce
a to a boolean value.
Anything that could be done with a hidden .__not__ method could also be
done, and I would say, better done, with an overt .invert method. For
instance, a mutable binary array class should likely have .invert to
flip each member in-place.
As it is now, anyone reading 'not a' can depend on the result being a
bool. And I think that is good.
--
Terry Jan Reedy
More information about the Python-ideas
mailing list