checking if a list is empty

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun May 15 20:36:19 EDT 2011


On Sun, 15 May 2011 10:33:38 -0700, rusi wrote:

> On May 15, 10:07 am, Steven D'Aprano <steve
> +comp.lang.pyt... at pearwood.info> wrote:
>>
>> I'm afraid I don't understand what you mean. Can you explain please,
>> what properties of "first class booleans" do you think are missing from
>> Python?

[snip]

I'm afraid I didn't find your discussion about reification, Platonism and 
linguistics very helpful. Some of it I disagree with, some I agree with, 
but in neither case do I see any relevance to the question of whether 
bools are first class objects in Python, and if not, why not.


> Reapplied back to the math/programming field, we find that if a value-
> domain (data-type) has to be first-class, it at the least has to be a
> denotable entity in the language which should be conformable with its
> abstract/expected properties.

Now you're getting somewhere!

> For example if my language seems to have entities like '2' '3' '+' but
> 2+3 does not work out equal to 5 we would (I hope!) not say the language
> has first-class numbers.

Well, that's a problem. By that definition, floats are not first class 
numbers. While 2+3 does work out to be equal to 5, other standard 
properties of the real number system do not apply:

>>> 0.3 + 0.4 - 0.3 == 0.4
False

Similarly, in many languages (including older versions of Python), 
neither are integers:

>>> 2147483647 + 1
Traceback (innermost last):
  File "<stdin>", line 1, in ?
OverflowError: integer addition


Other languages may wrap around, giving -1 or -2147483648.

So it seems that either we're forced to accept that neither floats nor 
integers are "first class", or instead back-track and ask:

"Hang on, who decides what the expected properties are?"



> But in order for any of this discussion to be possible, equality should
> be well-defined.
> Which means that in addition to being an equivalence relation it must
> have substitutivity


Can you show us a problem that is hard to solve in Python because ([1,2] 
and True) evaluates as True, but ([1,2] == True) evaluates as False?



> http://en.wikipedia.org/wiki/Equality_%28mathematics%
29#Some_basic_logical_properties_of_equality
> which is another form of a very fundamental principle attributed to
> Leibniz, the principle of identity of indiscernibles:
> http://en.wikipedia.org/wiki/Leibniz%27s_law

But Python truth values are not indiscernible. Do you think they must be?

If they are indiscernible, there can only be two unique values (possibly 
spelled "Veritas" and "Falsus" to avoid confusion with Python's True and 
False). But why must they be indiscernible?


> Seemingly you and Dijkstra are saying something similar when you say
> [1,2,3] is a way of writing true
> and he says 2<3 is a way of writing true. But on further examination
> (with Leibniz law above) Dijkstra's 2<3 = True will work consistently in
> all contexts but [1,2,3] = True will work sometimes and fail sometimes.

Please do not arbitrarily mix Python and mathematics syntax. What you 
have stated gives a SyntaxError.

[1,2,3] == True will work always, or you have a very buggy version of 
Python. It will always return False, as expected.


I suspect that in a boolean context, the operator you want is material 
biconditional, or XNOR, also known as "p if and only if q". Python does 
not have this as a built-in, but it's easy enough to write it:

def xnor(p, q):
    if p: return q
    else: return p if q else True

(I have deliberately written it to return one of the two arguments when 
possible. If you don't care for this behaviour, the else clause is even 
simpler: return not q)

If you don't like the name XNOR, rename it "equals" and be done. Nobody 
says that equality *must* be spelled with = or == as an infix operator. 
That would be a foolish insistence.

Another way would be to compare the canonical truth values for equality:

bool(p) == bool(q)

but of course there's nothing special about the canonical truth values 
except ease of use. One could choose any other values:

def canonical(flag):
    if flag: return "Nobody expects the Spanish Inquisition!!!"
    else: return None

canonical(p) == canonical(q)

The important thing is that Python's sense of equality doesn't just apply 
in the boolean domain, it applies to the broader any-arbitrary-Python-
object domain. Python's equals is too powerful to be limited to Python's 
truth values: it needs to distinguish between 42 and 23, while in the 
boolean domain one need not.

Consequently, if you want equality in the boolean domain, you need to use 
something other than the built-in == operator. Python doesn't allow you 
to override == for built-in objects, so the simplest, most straight-
forward way is with a function. Using such a function:

>>> equals = xnor
>>> equals( equals([1, 2], 42), equals("spam", 23) )
23

which is, naturally, just another way of spelling True.



> In mathSpeak we say, the definition of bool is not well defined In
> CSSpeak we say the definition is not first class.

That is not the normal definition of "first class" in computer science. 
The normal definition relates to whether a data type can be assigned to 
variables, passed to functions, and otherwise treated like ints or floats 
or other "first class" types. That certainly applies to truth values in 
Python, and bools.


> In the language of algebraic specifications, the slogan is "No
> confusion, No junk"
> eg
> http://www.informatik.uni-bremen.de/agbkb/lehre/ws06-07/casl/slides/
Datatypes-II.pdf
> 
> This is usually applied to specific models in a given language
> 
> But it could as well be applied to the models that a language supplies
> by default.
> And when we apply it to python's bool as a model of the abstract/math
> concept bool it has confusion and junk.

Well there is certainly confusion, but it's not in Python's model. The 
confusion seems to entirely rest in your mistake in thinking that the 
only valid way to do an equality test is with the built-in == syntax.



-- 
Steven



More information about the Python-list mailing list