
On Wed, Oct 12, 2011 at 7:44 PM, Nick Coghlan <ncoghlan@gmail.com> wrote:
On Thu, Oct 13, 2011 at 11:45 AM, Eric Snow <ericsnowcurrently@gmail.com> wrote:
Unless I misunderstood, Guido is basically saying the same thing (the "exposing" part, that is).
+1 on exposing start, step and end
+1
+1 on leaving it at that (unless it turns out to be a common case)
My reading is that Guido has reserved judgment on the second part for now. Options are:
- do nothing for 3.3 (+0 from me) - make sequence comparison the default (+1 from me) - make start/stop/step comparison the default (-1 from me)
Actually when I wrote that I was +1 on start/stop/step comparison and -1 on sequence (really: list) comparison. But I'd like to take a step back; we should really look at the use cases for comparing range objects. Since they don't return lists, you can't compare them to lists (or rather, they're always unequal). Because of this (and because it didn't work in 3.0, 3.1, 3.2) the proposed requirement that it should work the same as it did in Python 2 doesn't sway me. So what's the most useful comparison for range objects? When comparing non-empty ranges with step 1, I think we all agree. So we're left arguing about whether all empty ranges should be equal, and about whether non-empty ranges with step > 1 should compare equal if they have the same start, step and length (regardless of the exact value of stop). But why do we compare ranges? The first message in this thread (according to GMail) mentions unittests and suggests that it would be handy to check if two ranges are the same, but does not give a concrete example of such a unittest. The code example given uses list-wise comparison, but the use case is not elaborated further. Does anyone have an actual example of a unittest where being able to compare ranges would have been handy? Or of any other real-life example? Where it matter what happens if the range is empty or step is
1?
So, let me say I'm undecided (except on the desirability of an == test for ranges that's more useful than identity). FWIW, I don't think the argument from numeric comparisons carries directly. The reason numeric comparisons (across int, float and Decimal) ignore certain "state" of the value (like precision or type) is that that's how we want our numbers to work. The open question so far is: How do we want our ranges to work? My intuition is weak, but says: range(0) != range(1, 1) != range(1, 1, 2) and range(0, 10, 2) != range(0, 11, 2); all because the arguments (after filling in the defaults) are different, and those arguments can come out using the start, stop, step attributes (once we implement them :-).
If we do either of the latter, range.__hash__ should be updated accordingly (since 3.x range objects are currently hashable due to their reliance on the default identity comparison)
Sure. That's implied when __eq__ is updated (though a good reminder for whoever will produce the patch). (I'm also -1 on adding ordering comparisons; there's little disagreement on that issue.) PS. An (unrelated) oddity with range and Decimal:
range(Decimal(10)) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'Decimal' object cannot be interpreted as an integer range(int(Decimal(10))) range(0, 10)
So int() knows something that range() doesn't. :-) -- --Guido van Rossum (python.org/~guido)