# Comparisons and sorting of a numeric class....

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Jan 8 00:46:03 CET 2015

```Marko Rauhamaa wrote:

> Steven D'Aprano <steve at pearwood.info>:
>
>> int 0 is a falsey object
>> NoneType None is a falsey object
>> str 'hello' is a truthy object
>> float 23.0 is a truthy object
>
> I prefer the Scheme way:
>
>    #f is a falsey object
>
>    everything else is a truthy object

The Scheme way has no underlying model of what truthiness represents, just
an arbitrary choice to make a single value have one truthiness, and
everything else the other. It's just as meaningless and just as arbitrary
as the opposite would be:

#t is True
everything else is falsey

In both cases, you have the vast infinity of values apart from #f (or #t, as
the case may be) which are indistinguishable from each other under the
operation of "use in a boolean context". In other words, apart from #f or
#t, bool(x) maps everything to a single value. That makes it useless for
anything except distinguishing #f (or #t) from "everything else".

(I'm mixing scheme and python here, but I trust my meaning is clear.)

Given x of some type other than the Boolean type, bool(x) always gives the
same result. Since all non-Booleans are indistinguishable under that
operation, it is pointless to apply that operation to them.

I'd rather the Pascal way:

#t is True
#f is False
everything else is an error

That at least gives you the benefits (if any) of strongly-typed bools.

Python has a (mostly) consistent model for truthiness: truthy values
represent "something", falsey values represent "nothing" or emptiness:

Falsey values:
None
Numeric zeroes: 0, 0.0, 0j, Decimal(0), Fraction(0)
Empty strings '', u''
Empty containers [], (), {}, set(), frozenset()

Truthy values:
Numeric non-zeroes
Non-empty strings
Non-empty containers
Any other arbitrary object

The model isn't quite perfect (I don't believe any model using truthiness
can be) but the number of gotchas in the built-ins and standard library are
very small. I can only think of two:

- datetime.time(0) is falsey. Why midnight should be falsey is an
accident of implementation: datetime.time objects inherit from
int, and midnight happens to be represented by zero seconds.

- Empty iterators are truthy. Since in general you can't tell in
advance whether an iterator will be empty or not until you try
it, this makes sense.

--
Steven

```