Boolean tests [was Re: Attack a sacred Python Cow]

Terry Reedy tjreedy at udel.edu
Fri Aug 1 21:36:38 CEST 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