classification
Title: Add to "whats new": range(n) != range(n)
Type: Stage:
Components: Documentation Versions: Python 3.0, Python 3.1
process
Status: closed Resolution: wont fix
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: MLModel, georg.brandl, rhettinger, terry.reedy
Priority: normal Keywords:

Created on 2009-05-07 03:19 by MLModel, last changed 2009-05-14 18:10 by MLModel. This issue is now closed.

Files
File name Uploaded Description Edit
unnamed MLModel, 2009-05-08 19:34
Messages (11)
msg87357 - (view) Author: Mitchell Model (MLModel) Date: 2009-05-07 03:19
I just discovered to my (deep) surprise that
        range(n) != range(n)
I think that's worth including in the what's new document.
I realize that the document essentially says that in python 3 range
behaves the way xrange did in python 2 and that ranges have very little
behavior, but surely the lack of equality of two ranges whose string
representations are equal is enough of a surprise and difference from
python 2 to be worth an explicit comment. (Or maybe no-one ever compares
ranges? They are just for iteration? Even that should be said
explicitly. This is one of those things that I'm sure expert developers
look at and think is obvious but might trip up ordinary users.)
msg87457 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-05-08 18:41
Alternatively, range objects could have a .__eq__ method that compares
the (hidden) start, stop, and step attributes used to print the
representations.

As a workaround, str(r1)==str(rs) will work as expected.
msg87464 - (view) Author: Mitchell Model (MLModel) Date: 2009-05-08 19:34
Yes, that's why I was surprised. It's rare (isn't it?) to have str(a) 
== str(b) but a != b.  a not is b, sure, but a != b? Note also that 
list(range(n)) == list(range(n)). If the lists are equal and the 
strings are equal it's hard to see why the objects wouldn't be equal.

There are other things like range that define equality; for instance
	date.today() == datetime.date(2009, 5, 8)
Seems like ranges should define equals too.

However, I do understand the technical argument for saying not to use 
ranges except in prescribed places, largely for iteration.  Perhaps 
analagously, I discovered that webbrowser.open would open file URLs 
in their application on Macs (and perhaps Windows); when I suggested 
that behavior be added to the documentation of webbrowser what got 
added instead was a paragraph saying that although it might work it's 
neither supported nor portable. It could be that the right thing to 
do is instead of adding equality (though that would certainly be my 
preference) emphasize the statement that ranges have very little 
behavior, adding something like "in fact, two ranges are never equal" 
or something like that.

Either the documentation or the implementation should be changed -- 
it's just too much of a surprised to find that ranges aren't ever 
equal, especially when they were in Python 2.  (I'm still not 
claiming I can think of any logical reason for testing the equality 
of ranges. I stumbled on this while writing up a list of examples 
motivating pickling and trying to show for what kinds of values 
eval(str(value)) == value. I expected range to be one of them.

Here's another wrench, though: while a file is treated as a sequence 
of lines in for statements, I doubt anyone would want to ever compare 
files for equality. Possibly identity, to see if two open files are 
the same, but comparing the contents? That should be done under the 
program's control.

Sorry for the long-winded response. It wouldn't be as important if 
this were some corner of a little-used module, but range is really 
fundamental and it's better to get this right ASAP before people 
moving to Python 3 trip over it or rely on a behavior that might 
change in the future.
-- 
-- 

         --- Mitchell
msg87483 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-05-09 06:23
Please don't post html.  For whatever reason, it displayed as
hard-to-read marked-up html text when emailed (and my reader does
usually display html messages properly).  Perhaps the email mime-type
was wrong even though it looks ok in Firefox.
msg87507 - (view) Author: Mitchell Model (MLModel) Date: 2009-05-09 19:23
Sorry -- I did notice in the copies sent to me of my replies to bugs.python.org that there was HTML, but I can't  figure out why. I didn't use any style text in the message nor in my signature. I thought my email program only sent HTML when there was some styled text in the message. I just changed a setting that might fix this -- please tell me if you are seeing HTML in this.
-- 
-- 

        --- Mitchell
msg87513 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2009-05-09 21:44
Mitchell Model wrote:
> Mitchell Model <mlm@acm.org> added the comment:
> 
> Sorry -- I did notice in the copies sent to me of my replies to
> bugs.python.org that there was HTML, but I can't  figure out why. I
> didn't use any style text in the message nor in my signature. I
> thought my email program only sent HTML when there was some styled
> text in the message. I just changed a setting that might fix this --
> please tell me if you are seeing HTML in this.

No, looks great.  I believe for most (all?) mailers, '[x] sent html' 
*always* sends html, even if not 'needed'.
msg87738 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-05-14 14:13
Am inclined to reject this request.  We shouldn't get in the habit of
documenting what functions don't do.  In the past, no one seemed to have
any trouble with xrange() not being comparable to itself.  In the
present, there are many functions that return iterators instead of
lists, so the expectation for comparability will be even lower.

The main problem with anti-documentation is that bringing up the topic
can plant it in a reader's memory in a confusing way, "I think I read
something about ranges and comparability ...".  IOW, just talking about
it makes it more likely that someone will be led to making a fallacious
assumption.

Likewise, I don't want to put in a recommendation about comparing the
repr() of ranges either.  The problem is that the (start,stop,step)
tuples can differ but the ranges can be the same:

   >>> args1 = 0, 101, 5
   >>> args2 = 0, 102, 5
   >>> args1 == args2
   False
   >>> list(range(*args1)) == list(range(*args2))
   True

Also, I'm not worried about this one because comparing the output of
range() was not a common thing to do even in Py2.x.
msg87740 - (view) Author: Mitchell Model (MLModel) Date: 2009-05-14 16:40
Sounds right. (1) I was raising the issue in case either the behavior was unintended or the documentation should mention it; (2) I realize that comparing ranges is strange; (3) I understand that range works in 3 the way xrange worked in 2, and that the what's new documentation says that range replaces xrange (4) you're point about ranges with steps clinches the issue, I think -- certainly equality of ranges should not have to compute the range -- they should be thought of as generators (and maybe documented as such -- for all I know, since I haven't looked, they are implemented that way); (5) I agree that range behaves like an iterator -- its documentation at the introduction to sequence tyhpes even points out that in, not in, max, and min are inefficient (6) the specific documentation for range explicitly states that they have very little behavior supporting only indexing, iteration, and len().

Your comments were very helpful in explicitly laying out the issues regarding implementing equality and the relative unimportance of the change in behavior, and I now have the explanation I wanted.

The only thing that still makes me uncomfortable is that it wouldn't be such a big deal to point out in the 3.0 "what's new" document where the change to range is mentioned in a bullet that range supports only indexing, iteration, and len, and that operations such as in and not in and functions such as max and min are inefficient because, except in when true, they require iterating over the entire range. Since these are specified in the actual documentation of range I believe they should be added to the what's new, where the change to range is described. I agree that what things don't do should rarely be documented, but if they no longer do something that they used to do, that should go in the "what's new" document -- at least in the form of an explicit list of what they do do. The only argument I can see against doing that is that the document says that "range() now behaves like xrange() used to behave", but I don't feel that is sufficiently explicit for people who have used range extensively but never or rarely xrange or who don't think about its implications. Maybe the "what's new" should just say that range() acts like an iterator.

All in all I'm satisfied and appreciative, except that I'm still left with the feeling that something about range() should be added to the 3.0 "what's new".
-- 
-- 

        --- Mitchell
msg87742 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-05-14 17:04
At some point, a person just needs to read the regular docs for range().
msg87746 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-05-14 17:18
I should have been clearer.  It is not the function of whatsnew to show
all aspects of 2-to-3 changes.  It is enough to say that range() no
longer returns a list and instead returns what used to be an xrange()
object.  At that point, the job of full documentation of the function is
left to the main docs.  The whatsnew entries are supposed to be very
brief hints about where to look next.
msg87749 - (view) Author: Mitchell Model (MLModel) Date: 2009-05-14 18:10
Ah. I see. I hadn't realized that. OK, I see how all the pieces fit together now. Thanks for all the explanations. They'll help me understand better what kinds of comments to make on the documentation.
-- 
-- 

        --- Mitchell
History
Date User Action Args
2009-05-14 18:10:50MLModelsetmessages: + msg87749
2009-05-14 17:18:44rhettingersetmessages: + msg87746
2009-05-14 17:04:30rhettingersetstatus: open -> closed
resolution: wont fix
messages: + msg87742
2009-05-14 16:40:49MLModelsetmessages: + msg87740
2009-05-14 14:13:22rhettingersetmessages: + msg87738
2009-05-11 20:39:18rhettingersetassignee: georg.brandl -> rhettinger

nosy: + rhettinger
2009-05-09 21:44:47terry.reedysetmessages: + msg87513
2009-05-09 19:23:59MLModelsetmessages: + msg87507
2009-05-09 06:24:28terry.reedysetmessages: + msg87483
2009-05-08 19:34:26MLModelsetfiles: + unnamed

messages: + msg87464
2009-05-08 18:41:45terry.reedysetnosy: + terry.reedy
messages: + msg87457
2009-05-07 03:19:23MLModelcreate