The Python Oracle

What is the root of the distinction in the meaning of equality between C++ and Python?

This video explains
What is the root of the distinction in the meaning of equality between C++ and Python?

--

Become part of the top 3% of the developers by applying to Toptal
https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzling Curiosities

--

Chapters
00:00 Question
03:21 Accepted answer (Score 30)
05:59 Answer 2 (Score 4)
07:12 Answer 3 (Score 3)
07:50 Thank you

--

Full question
https://stackoverflow.com/questions/4906...

Question links:
[became aware]: https://stackoverflow.com/q/49060812/704...
[there is little (no?) precedent in Python for equality comparisons raising errors]: https://stackoverflow.com/a/49060836/704...
[if [an object] raises every time it is compared to a [object of a different type], it will break any container it is added to]: https://stackoverflow.com/a/49061174/704...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #c++

#avk47



ACCEPTED ANSWER

Score 30


The fundamental intent in Python has changed over time. At the start, and until late in the development of Python 2, it was essentially the case that any two objects could be compared. Even mixed-type comparisons that made no intuitive sense, like:

>>> 3 < [1]
True

In cases like that, it was actually the string names of the types that were compared, and the result above was due to that, as strings, "int" < "list". This was driven mostly by a misguided (in hindsight) attempt to impose a total ordering on all objects.

Looking ahead to Python 3, the intent changed, and started to be implemented with the datetime module types (which were introduced in Python 2): mixed-typed <, <=, >, and >= comparisons that made scant intuitive sense were to raise exceptions instead, while senseless mixed-type == would always return False and senseless mixed-type != always True.

>>> import datetime
>>> n = datetime.datetime.now()
>>> n < 3
Traceback (most recent call last):
  ...
TypeError: can't compare datetime.datetime to int
>>> n >= 3
Traceback (most recent call last):
  ...
TypeError: can't compare datetime.datetime to int
>>> n == 3
False
>>> n != 3
True

Python 3 strives to act "like that" generally. Of course there are exceptions. For example, when comparing objects of different numeric types (like integers and floats), they're usually coerced to a common type under the covers.

I was deeply involved in these decisions (and wrote the datetime module), so you can trust me on that. But as to what C++ intends, you'll have to ask someone else ;-)

A Bit More Info

I should add that, up until the introduction of "rich comparisons" in Python 2, all comparisons funneled through a cmp() protocol: in the CPython implementation, comparing two objects returned one of the integers in [-1, 0, 1]. __cmp__() methods had no idea which of <, <=, ==, !=, >, and >= was actually desired. So while the "compare any two things no matter what" original design was disliked early on, it was technically difficult to get away from before rich comparisons were incorporated into the language. Then it became straightforward (if tedious).




ANSWER 2

Score 4


It's not so much a "philosophical" matter as a difference between dynamic language like Python and a strongly-typed language like C++. Because variables can hold any type in Python, and that type can change dynamically, it makes sense for the meaning of equality to be looser in Python than something like C++. You don't want exceptions to be raised because you asked whether two variables were equal - in principle the exception would need to be raised at runtime since Python is interpreted, and in a scripting language you would much prefer the comparison to return false in this circumstance. Similarly you can say something like:

if (foo):
    [some code]

even though foo is not boolean. So you have the concept of things being "falsey", which is weird from a strongly-typed world perspective, but useful in a scripting context.

In short the philosophical explanation rests on the respective philosophy of dynamic and strongly typed languages.




ANSWER 3

Score 3


I see no one expanded on the C++ side, so here are my two cents.

In C++ every object (and variable) has a definitive type which cannot change, so a type mismatch can be detected at compile-time. Since the result of equality between two unrelated objects is "duh, of course not", and C++ puts high value on detecting errors early, it simply doesn't compile at all.