I've attached the first draft of PEP 204, Range Literals, which I just uploaded to CVS as well. If anyone finds time to review it, or the proposed implementation (patch #100902 on SourceForge) please do. I'm not sure what to do with the patch... Guido said as much as 'apply it'(*), but I doubt anyone really looked at it yet ;) I wrote this using 'joe', which is still my favorite editor, because despite many, many minutes of effort, xemacs simply refused to do what I wanted it to do. How do you 're-flow' a paragraph, for instance, or enable word wrapping, or better yet: word wrapping with autoindentation ? If anyone has a quick-and-dirty howto on [x]emacs, feel free to share ;) (* In http://www.python.org/pipermail/python-dev/2000-July/013234.html) -- Thomas Wouters <thomas@xs4all.net> Hi! I'm a .signature virus! copy me into your .signature file to help me spread!
Thomas Wouters <thomas@xs4all.net>:
I wrote this using 'joe', which is still my favorite editor, because despite many, many minutes of effort, xemacs simply refused to do what I wanted it to do. How do you 're-flow' a paragraph,
Esc-g
for instance, or enable word wrapping, or better yet: word wrapping with autoindentation ?
Esc-x set-variable auto-fill 1 To always enable it in text mode, add (setq text-mode-hook '(lambda () (auto-fill-mode 1))) to your .emacs file. Emacs will detect your indent level and honor it.
One possible solution to the discrepancy of requiring the `end' argument in range literals is to allow the range syntax to create a `generator', rather than a list, such as the `xrange' builtin function does. However, a generator would not be a list, and it would be impossible, for instance, to assign to items in the generator, or append to it.
Not so. Appending to the generator object, or assigning to it, would simply force eager rather than lazy evaluation of the generator. This would have to throw an exception on infinite generators. But all this is academic until Python has continuations, really. For finite cases eager vs. lazy only makes a difference in the timing of computations, not their result. While this could be semantically significant for some list comprehensions, it won't be for range literals. (You might want to go look at Haskell or Icon to learn more about how lazy and eager evaluation interact.)
Should it be possible to mix range syntax with normal list literals, creating a single list, like so:
>>> [5, 6, 1:6, 7, 9] to create [5, 6, 1, 2, 3, 4, 5, 7, 9]
I'm completely neutral on this.
However, as the syntax and semantics of list comprehensions are still subject of hot debate, these issues are probably best addressed by the `list comprehensions' PEP.
Agreed.
Range literals accept objects other than integers: it performs PyInt_AsLong() on the objects passed in, so as long as the objects can be coerced into integers, they will be accepted. The resulting list, however, is always composed of standard integers.
Should range literals create a list of the passed-in type ? It might be desirable in the cases of other builtin types, such as longs and strings:
>>> [ 1L : 2L<<64 : 2<<32L ] >>> ["a":"z":"b"] >>> ["a":"z":2]
However, this might be too much `magic' to be obvious. It might also present problems with user-defined classes: even if the base class can be found and a new instance created, the instance may require additional arguments to __init__, causing the creation to fail.
+1. Whenever possible, builtins ought to do something intuitive with any type that is passed in, and range literals have an obvious and intuitive definition for any well-ordered base type. I think it would be more surprising if this did *not* work for well-ordered scalar types. I don't view the issue for user-defined classes as a showstopper; it would be OK, and semantically reasonable, to throw an exception in this case.
The PyList_FromRange() and PyList_GetLenOfRange() functions need to be classified: are they part of the API, or should they be made private functions ?
No opinion. -- <a href="http://www.tuxedo.org/~esr">Eric S. Raymond</a> ...the Federal Judiciary...an irresponsible body, working like gravity by night and by day, gaining a little today and a little tomorrow, and advancing its noiseless step like a thief over the field of jurisdiction until all shall be usurped from the States; and the government of all be consolidated into one.
On Tue, Jul 18, 2000 at 11:08:23AM -0400, esr@thyrsus.com wrote:
Thomas Wouters <thomas@xs4all.net>:
One possible solution to the discrepancy of requiring the `end' argument in range literals is to allow the range syntax to create a `generator', rather than a list, such as the `xrange' builtin function does. However, a generator would not be a list, and it would be impossible, for instance, to assign to items in the generator, or append to it.
Not so. Appending to the generator object, or assigning to it, would simply force eager rather than lazy evaluation of the generator. This would have to throw an exception on infinite generators.
(You might want to go look at Haskell or Icon to learn more about how lazy and eager evaluation interact.)
Well, I had an xrange() like generator in mind. There currently isn't a very good way for a generator to turn itself into a list, unless it's some kind of polymorphic object that behaves one way until it gets assigned to... In which case I wouldn't want to meet it in a dark alley, alone, at night, without my language reference printout. I don't have the human resources to do an in-depth study of generators (or other languages) right now. The idiots I have to cooperate with at work (from our parent company) are sucking all life out of me, in a bad way ;P
Should range literals create a list of the passed-in type ? It might be desirable in the cases of other builtin types, such as longs and strings:
[..]
However, this might be too much `magic' to be obvious. It might also present problems with user-defined classes: even if the base class can be found and a new instance created, the instance may require additional arguments to __init__, causing the creation to fail.
+1. Whenever possible, builtins ought to do something intuitive with any type that is passed in, and range literals have an obvious and intuitive definition for any well-ordered base type. I think it would be more surprising if this did *not* work for well-ordered scalar types.
Well, I guess I agree. The above was just a bit of 'Red Red Wine' induced brainstorm, but on reflection it does seem logical. The one-dimensionality of range and xrange always bothered me ;) The biggest problem is, however, how to create a 'range' of a specific type of object, given a start, step and end object. A new PyNumberMethods member 'int_range' ? Or some kind of 'newobject_fromnumber' protocol ? How about we checkin the current patch, which does what the PEP describes, and continue the PEP for the sake of these issues ? :)
I don't view the issue for user-defined classes as a showstopper; it would be OK, and semantically reasonable, to throw an exception in this case.
Agreed. And thanx for the emacs pointers ! :) -- Thomas Wouters <thomas@xs4all.net> Hi! I'm a .signature virus! copy me into your .signature file to help me spread!
Thomas Wouters <thomas@xs4all.net>:
Well, I guess I agree. The above was just a bit of 'Red Red Wine' induced brainstorm, but on reflection it does seem logical. The one-dimensionality of range and xrange always bothered me ;) The biggest problem is, however, how to create a 'range' of a specific type of object, given a start, step and end object. A new PyNumberMethods member 'int_range' ? Or some kind of 'newobject_fromnumber' protocol ?
Let's worry about that later. For now, throwing an exception is OK.
How about we checkin the current patch, which does what the PEP describes, and continue the PEP for the sake of these issues ? :)
+1. -- <a href="http://www.tuxedo.org/~esr">Eric S. Raymond</a> If I were to select a jack-booted group of fascists who are perhaps as large a danger to American society as I could pick today, I would pick BATF [the Bureau of Alcohol, Tobacco, and Firearms]. -- U.S. Representative John Dingell, 1980
Thomas Wouters wrote:
I've attached the first draft of PEP 204, Range Literals, which I just uploaded to CVS as well. If anyone finds time to review it, or the proposed implementation (patch #100902 on SourceForge) please do. I'm not sure what to do with the patch... Guido said as much as 'apply it'(*), but I doubt anyone really looked at it yet ;)
Well, I can't say I really looked at it (the patch touches areas where I would deny me all too much expertise), but as far as I could understand it, it looks fine to me. This considered, I am still +1 on it. Peter -- Peter Schneider-Kamp ++47-7388-7331 Herman Krags veg 51-11 mailto:peter@schneider-kamp.de N-7050 Trondheim http://schneider-kamp.de
Should range literals create a list of the passed-in type ? It might be desirable in the cases of other builtin types, such as longs and strings: >>> [ 1L : 2L<<64 : 2<<32L ] >>> ["a":"z":"b"] >>> ["a":"z":2] However, this might be too much `magic' to be obvious. Well the step argument is of debatable utility for strings but ["0":"9"] seems mildly useful. Also, it makes sense to create a range of floating point numbers. If we were going to do this, we would probably have an overloadable operator: string.__range__( start=None, end=None, step=None ) It could return a sequence of whatever kind. I'm not clear why we can't implement it as a function call to __builtins__.range . -- Paul Prescod - Not encumbered by corporate consensus Just how compassionate can a Republican get before he has to leave the GOP and join Vegans for Global Justice? ... One moment, George W. Bush is holding a get-to-know-you meeting with a bunch of gay Republicans. The next he is holding forth on education or the environment ... It is enough to make a red-blooded conservative choke on his spotted-owl drumstick. - April 29th, Economist
On Tue, Jul 18, 2000 at 07:37:29PM -0500, Paul Prescod wrote:
I'm not clear why we can't implement it as a function call to __builtins__.range .
I did that mostly because of the error messages. Giving the range() error messages when using [1:100] is a bit confusing. Can't think of any other reason, though. -- Thomas Wouters <thomas@xs4all.net> Hi! I'm a .signature virus! copy me into your .signature file to help me spread!
On Tue, 18 Jul 2000, Paul Prescod wrote:
Should range literals create a list of the passed-in type ? It might be desirable in the cases of other builtin types, such as longs and strings:
>>> [ 1L : 2L<<64 : 2<<32L ] >>> ["a":"z":"b"] >>> ["a":"z":2]
However, this might be too much `magic' to be obvious.
Too much magic. Remember the analogy is with the slice operator: lst[start:end]. Only integers work there, and only integers are acceptable to range() now, so it's simpler and happier all around to keep the range literals to just integers too.
Well the step argument is of debatable utility for strings but ["0":"9"] seems mildly useful. Also, it makes sense to create a range of floating point numbers.
Not useful enough, i think, to be worth it. If you need to do a range check, you can still say "a" <= x <= "z". When working with ranges or regions on the number line, you probably want something more specifically designed for that. (For example, you might want to talk about open, closed, or half-open intervals.) If we're going to consider the feature, E's CoordinateSpaces and Regions are worth a serious look. Hmm. I don't have a good reference on that. I'll post one when i find it. -- ?!ng
Should range literals create a list of the passed-in type ? It might be desirable in the cases of other builtin types, such as longs and strings: >>> [ 1L : 2L<<64 : 2<<32L ] >>> ["a":"z":"b"] >>> ["a":"z":2] However, this might be too much `magic' to be obvious. Well the step argument is of debatable utility for strings but ["0":"9"] seems mildly useful. Also, it makes sense to create a range of floating point numbers. If we were going to do this, we would probably have an overloadable operator: string.__range__( start=None, end=None, step=None ) It could return a sequence of whatever kind. I'm not clear why we can't implement it as a function call to __builtins__.range . -- Paul Prescod - Not encumbered by corporate consensus Just how compassionate can a Republican get before he has to leave the GOP and join Vegans for Global Justice? ... One moment, George W. Bush is holding a get-to-know-you meeting with a bunch of gay Republicans. The next he is holding forth on education or the environment ... It is enough to make a red-blooded conservative choke on his spotted-owl drumstick. - April 29th, Economist
participants (5)
-
esr@thyrsus.com
-
Ka-Ping Yee
-
Paul Prescod
-
Peter Schneider-Kamp
-
Thomas Wouters