code review

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Jul 1 08:54:01 CEST 2012


On Sun, 01 Jul 2012 13:48:04 +1000, Chris Angelico wrote:

> On Sun, Jul 1, 2012 at 1:23 PM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
>> All the worse for those languages, since they violate the semantics of
>> mathematical notation.
> 
> Not so. It simply means that booleans are nothing special. In REXX,
> there are no data types at all, and "1" and "0" are your booleans. In C,
> boolean and comparison operations return integers, either 1 or 0. 

This has nothing to do with the presence of a Boolean type or not. It is 
about syntax, not types.

Python didn't have bools until relatively recently but it still had 
chained comparisons. In Python2.1 and older, boolean and comparison 
operations return integers, either 1 or 0, precisely the same as C.

You can even use chained comparisons for types that don't interpret the 
operators as comparisons:

py> class Funny:
...     def __init__(self, x):
...             self.x = x
...     def __lt__(self, other):
...             return Funny(self.x + 3*other.x)
...     def __str__(self):
...             return str(self.x)
...
py> a = Funny(2)
py> b = Funny(3)
py> c = Funny(4)
py>
py> print a < b < c
15
py> print (a < b) and (b < c)
15

Although the interpretation of such may not be useful.



> Same
> was true of Python early on, if I understand correctly. It's not
> shameful.

The first public release of Python, 0.9, included chained comparisons. 
This was even before the language had == for equality tests!

steve at runes:~$ ./python0.9.1
>>> print 2 < 3 < 4
1
>>> print 2 = 2 = 2
1
>>> print (2 = 2) = 2
0


So no, Python has always included chained comparisons, and yes, it is 
shameful that a language would force you to unlearn standard notation in 
favour of a foolish consistency with other operators. Comparisons aren't 
special because they return bools. They are special because of the way 
they are used.

C treats comparison operators as if they were arithmetic operators, and 
so the behaviour of a chained comparison is the same as the behaviour as 
a sequence of arithmetic operators: a foolish consistency. Python treats 
comparison operators as comparison operators, and gives them behaviour 
appropriate to comparisons.

The fact that so many languages do the wrong thing here, and so few 
emulate standard mathematical notation, is symptomatic of the lousy state 
of language design.

Pascal might be verbose, but at least it makes it harder to write code 
that silently does the wrong thing -- it prevents you from writing 
chained comparisons which do the wrong thing, and forces you to be 
explicit. C has the worst of both worlds:

- it allows the standard concise mathematical notation a < x < b
- but it quietly changes the semantics to something that the user 
  hardly ever wants

thus giving the maximum number of bugs with the minimum amount of 
convenience.


>> The more I learn about C, the less I want to know about C. What sort of
>> crazy language designer thought that having
>>
>> 2 == 2 == 2
>>
>> return 0 (false) was a good idea?
> 
> It makes perfect sense though; 

Not in English-speaking countries with a culture of writing chained 
comparisons in mathematics and allowing them in natural language:

"Rock is beaten by Paper, is beaten by Scissors".



-- 
Steven



More information about the Python-list mailing list