Boolean tests [was Re: Attack a sacred Python Cow]
Terry Reedy
tjreedy at udel.edu
Fri Aug 1 15:36:38 EDT 2008
> Nevertheless, I think this is probably the best example of the
> enhanced polymorphism of "if x" yet. I'm kind of surprised no one
> came up with it.)
I think of Python code as 'generic' rather than 'polymorphic'. I am not
sure if that is a real difference or not, since I am a bit fuzzy on the
meaning of 'polymorphic' in this context.
The generality of 'if x:' depends on the context. If x is defined as a
number by doc or previous code (or possibly even by subsequent code),
then 'if x:' is equivalent to 'if x != 0:'. At this point, it is a
stylistic argument which to use.
But here is an example where 'if x:' is more generic.
def solve(a,b):
'a and b such that b/a exists'
if a:
return a/b
else:
raise ValueError('a not invertible, cannot solve'
Now suppose we have a matrix class (2x2 for simplicity and realism).
Its __bool__ (3.0) method implements 'is non-singular'. As written
above, solve(mat,vec) works (with compatible mat and vec sizes), but it
would not with 'if a != 0:'.
Of course, the issue goes away by not looking before the leap:
def solve(a,b):
return a/b
# let callers deal with exceptions
or
try:
return a/b
except...
# raise customized error
> In general, the ability to take advantage of "if x" polymorphism
> across numeric, container, and other types depends on the something/
> nothing dichotomy to be applicable.
Numbers and sequences are both sortable with the same algorithm if it is
written to be generic. However, 0 is nothing special when sorting, so
'if x:' would not be used.
All collections are (or should be) iterable. But a boolean test is not
part of the current iteration protocol. One might want to test whether
the iterable starts with anything before setting things up, but that
either exclude most iterators or requires wrapping them in a lookahead
class with a __bool__ method.
In general, asking code to apply across numeric, container, and other
classes is asking too much. Python code can be generic only within
protocol/interface categories such as number-like, sortable, and
iterable. But making tests too specific can unnecessarily prevent even
that.
> Something versus nothing is a useless concept most of the time, but
> occasionally finds use in human interaction cases such as printing.
It is sometimes useful within categories of classes, as in my solve example.
Terry Jan Reedy
More information about the Python-list
mailing list