Comparisons and sorting of a numeric class....

Ian Kelly ian.g.kelly at gmail.com
Fri Jan 16 00:01:56 EST 2015


On Thu, Jan 15, 2015 at 6:45 PM, Andrew Robinson
<andrew3 at r3dsolutions.com> wrote:
> Then I look at python development historically and look at the built in
> class's return values for compares; and I notice; they have over time become
> more and more tied to the 'type' bool.  I expect sometime in the future that
> python may implement an actual type check on all comparison operators so
> they can not be used to return anything but a bool.

Let's see what the documentation says about this:

"""
A rich comparison method may return the singleton NotImplemented if it
does not implement the operation for a given pair of arguments. By
convention, False and True are returned for a successful comparison.
However, these methods can return any value, so if the comparison
operator is used in a Boolean context (e.g., in the condition of an if
statement), Python will call bool() on the value to determine if the
result is true or false.
"""

https://docs.python.org/3/reference/datamodel.html#object.__lt__

So the docs explicitly promise that comparison methods can return any
value. Changing this would break backward compatibility (in particular
it would break a lot of DSLs), so it's not going to happen any time
soon, and you have nothing to worry about here.

> (eg:  I already noticed
> a type check on the return value of len() so that I can't return infinity,
> even when a method clearly is returning an infinitely long iterator -- such
> as a method computing PI dynamically.  That suggests to me that there is
> significant risk in python of having type checking on all __xx__ methods in
> the future. )  This inspection is what points me foremost to saying that
> very likely, I am going to want a bool or subtye of it (if possible) as a
> return type as self defense against future changes in Python -- although at
> present, I can still get away with returning other types if bool turns out
> to be impossible.

I suspect the reason __len__ must return an int is largely historical.
Back before __iter__ existed, the way Python did iteration was by
calling __len__ and then calling __getitem__ for each index between 0
and the result. Obviously for this to work, the result had to be an
int, and infinite iterators didn't exist in this era either.

Nowadays, that sort of iteration is non-standard, but Python will
still fall back on it if __iter__ isn't defined.

> So, your first alternative is the most at risk of future problems due to
> constraints likely to be placed on comparison return types ; and as I don't
> want to do much maintenance on my library in the future -- I don't think
> that is a very good choice for making my library with.

Except that the risk you describe is fictitious.

>>> One example: It can also be a union.
>>
>> I don't understand what you think this means. I know what *I* think it
>> means, but "subclass = union" doesn't make sense to me, so wonder what
>> you think it means.
>
>
> It's a fringe use-case in Python that I don't think many people use/know
> about.  I was just being thorough in listing it.
>
> I haven't seen it used in actual python code myself -- but I know from the
> literature I've read on Python that it is occasionally used in a manner
> analogous to that of C/C++.
>
> In C/C++ unions are a datatype that allow two (or more) different types of
> data to be defined as held by one object, but only one of them is allowed to
> be initialized at a time because their location in computer memory which
> overlaps.  C places no restrictions on the compatibility of the datatypes --
> which is different than Python, but Python has a similar ability.
>
> In Python, when multiple inheritance is invoked -- it does some kind of
> check on the base types for compatibility; but still appears to be able / or
> simply does overlap the allocated memory for the different base types; eg:
> according to several sources I have read (at least on C-python internals).
>
> So one can semantically instantiate a subclass of one subtype without
> semantically instantiating the other.
>
> ALl I know about it is what I have seen it in Python literature -- and I
> tested the examples I was shown to see if they still work, and they do --
> and noted that at least at one time Guido apparently thought it was a good
> idea ; but I haven't pursued it beyond that.

Do you have a link? I have no idea what you're referring to, and I
suspect that you're confused. You can't do multiple inheritance from
types that would internally have overlapping memory.  For example:

>>> class Foo(list, dict): pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: multiple bases have instance lay-out conflict

> I'm getting the message that the reason Guido though this was important was
> because the historical meaning of bool is more important than the idea that
> metastability is an issue to be dealt with at the same time as the data
> value -- like electrical engineers do regularly.

Maybe because Python wasn't written for electrical engineers. It's a
general purpose boolean algebra for a general purpose programming
language.



More information about the Python-list mailing list