Operator Precedence/Boolean Logic

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Jun 23 04:48:23 EDT 2016


On Thursday 23 June 2016 18:17, Antoon Pardon wrote:

> No zero is not nothing.

I think you have just disagreed with about four thousand years of 
mathematicians and accountants.

In fact, mathematicians were so hung up about zero being nothing, that it took 
about three thousand years before they accepted zero as a number (thanks to 
Indian mathematicians, via Arab mathematicians).

> If zere is nothing and an empty list is nothing,
> I would expect zero to be an empty list or that they could be used
> interchangebly.

You must have real trouble with statically typed languages then. Some of them 
won't even let you add 0.0 + 1 (since 0.0 is a float and 1 is an int).

> For instance in a project of mine polling for information and
> receiving an empty list is different from receiving None.

Okay. How is this relevant to the question of bools? If Python had "real bools" 
(in, say, the Pascal sense) you would still need to distinguish None from an 
empty list:

if info is None:
   print("done")
elif info:  # duck-typing version
            # "real bools" version uses "info != []" instead
   print("processing...")
else:
   print("nothing to process")


In fact, in this case chances are you probably don't even care to distinguish 
between empty and non-empty lists. What (I imagine) you probably care about is 
None versus any list:

if info is None:
   print("done")
else:
    for item in info:
        print("processing...")


> I rarely need tests where any truthy value will branch in one
> direction and any falsy value in the other.

That's reasonable. Few people do, except in the general case that they write 
some code that accepts any arbitrary truthy value. But more often, you expect 
that you are inspecting an object of some specific type, say, a sequence (list, 
tuple, deque, etc):

if seq:
    process()
else:
    handle_empty_case()


or a mapping (dict, UserDict, etc):

if mapping:
    process()
else:
    handle_empty_case()


or a Widget:

if widget:
    process()
else:
    handle_empty_case()


where you ask the object in question whether or not it should be considered 
empty ("nothing") or not ("something"), rather than having to call a type-
specific piece of code for each one:

if len(seq) == 0: ...

if mapping.isempty(): ...

if widget.isnullwidget(): ...



It's just duck-typing. Bools have certain behaviour in certain contexts, and 
*all* objects get the opportunity to quack like a bool in that context.



-- 
Steve




More information about the Python-list mailing list