Guido van Rossum wrote:
Thanks. Maybe I can nudge you a little more in the direction of my proposal by speaking about equivalence classes. A proper == function partitions the space of all objects into equivalence classes, which are non-overlapping sets such that all objects within one equivalence class are equal to each other, while no two objects in different classes are equal. (Let's leave NaN out of it for now; it does not have a "proper" == function.) There's a nice picture on this Wikipedia page: http://en.wikipedia.org/wiki/Equivalence_relation
Both proposals define proper equivalence classes -- there is no difference in this regard. In one proposal, equivalence is defined by identical behaviour, in the other equivalence is defined by identical parameters at creation time.
I still strongly lean towards the definition based on identical behaviour. If it wasn't for this particular choice of representation of ranges, there wouldn't be any way to distinguish the objects
range(3, 8, 3)
range(3, 9, 3)
They would be the same in every respect. It feels entirely artificial to me to consider them as not equal just because we used different parameters to create them (and someone chose to include these parameters in the representation).
BTW, I like Raymond's observation, and I agree that we should add slicing to range(), given that it already supports indexing; and slicing is a nice way to normalize the range. I just don't think that the status quo is better than either of the two proposed definitions for __eq__.
range() already supports slicing, and it already does this:
>>> r0 = range(3, 8, 3) >>> r1 = r[:] >>> r1 range(3, 9, 3)
If we adopted equality based on start/stop/step, this would lead to the somewhat paradoxical situation that r0 != r0[:], in contrast to the behaviour of all other sequences in Python.