Range Operation pre-PEP

1658 views
Skip to first unread message

Roman Suzi

unread,
May 8, 2001, 3:44:20 AM5/8/01
to pytho...@python.org, tho...@xs4all.net
Hello!

What is below is a half-baked proposal for new built-in
Python operation. If anybody wants to raise this flag
again and fill gaps, please do so.

(I have not studied PEP howto much, so probably I missed
something important.)

I hope the idea of ".." is quite simple: make special syntactic
form for xrange (range). I am not into C to reference-implement this
feature, so if anybody could do it...

All in all, I think the feature is most wanted/useful by/for beginners.

---------------------------

PEP: ???
Title: Range Operation
Version: $Revision: 1.0 $
Author: r...@onego.ru (Roman Souzi), derived from tho...@xs4all.net (Thomas
Wouters)'s rejected PEP 204
Status:
Type: Standards Track
Python-Version: 2.0
Created:
Post-History:

Introduction

This PEP describes the `range operation' proposal for Python 2.?.
This PEP tracks the status and ownership of this feature, slated
for introduction in Python 2.?. It contains a description of the
feature and outlines changes necessary to support the feature.
This PEP summarizes discussions held in mailing list forums.

The feature is needed in Python because it allows beginners
to learn for loop before learning range/xrange functions
and adds more clarity to the program because of similarity
with mathematical notation.

List ranges

Ranges are sequences of numbers of a fixed stepping, often used in
for-loops. The Python for-loop is designed to iterate over a
sequence directly:

>>> l = ['a', 'b', 'c', 'd']
>>> for item in l:
... print item
a
b
c
d

However, this solution is not always prudent. Firstly, problems
arise when altering the sequence in the body of the for-loop,
resulting in the for-loop skipping items. Secondly, it is not
possible to iterate over, say, every second element of the
sequence. And thirdly, it is sometimes necessary to process an
element based on its index, which is not readily available in the
above construct.

For these instances, and others where a range of numbers is
desired, Python provides the `range' builtin function, which
creates a list of numbers. The `range' function takes three
arguments, `start', `end' and `step'. `start' and `step' are
optional, and default to 0 and 1, respectively.

The `range' function creates a list of numbers, starting at
`start', with a step of `step', up to, but not including `end', so
that `range(10)' produces a list that has exactly 10 items, the
numbers 0 through 9.

Using the `range' function, the above example would look like
this:

>>> for i in range(len(l)):
... print l[i]
a
b
c
d

Or, to start at the second element of `l' and processing only
every second element from then on:

>>> for i in range(1, len(l), 2):
... print l[i]
b
d

There are disadvantages with this approach:

- Clarity of notation: beginners need to remember function name,
its difference from xrange while other languages use syntactical
construct for the same purpose, not a function.

- what else?

The Proposed Solution

The proposed implementation uses new syntactic
entity to specify range operation, as shown below:

>>> for i in 1 .. 5:
... print i
1
2
3
4
5

Or in extended form to specify a step:

>>> for i in (1, 3) .. 5:
... print i
1
3
5

The new operation ".." generates xrange object
on by following rule:

a1 .. an

(a1, a2) .. an

is equivalent to:

xrange(a1, an+1[, a2-a1])

or other analog of xrange is that is applicable to the
type.

N.B. Operation ".." deviates from slice notations.
This is so in accordance with mathematical notation
of ranges.

There are no implicit forms of "..", that is, a1 and an must
be present.

To overload ".." operation in user-defined classes,
specific type must implement method
__range__(self, a1, an, a2=1). This method must return either
iterator object or a list.

In the table of operation priorities, .. operation must have less
(or equal) priority than lambda but more priority than
comma-separated display.

The implementation of range-literals will need changes
backward-compatible changes to built-in xrange() function
to allow calling __range__ if the type is not a built-in
object. (or is it already done?)

Otherwise, ".." is syntactical "sugar" for xrange().

Reference Implementation

".." is a binary operation which if the first argument is 2-tuple,
uses xrange() with 3 arguments (as shown above) and if it is
a 1-tuple or other object, then it evaluates xrange with two
arguments (step=1).

TODO. Anybody?

Open issues

- I'd liked to see 1, 3 .. n syntax instead of (1, 3) .. n, but
the later will interfere with comma-separated lists.

- How does will couple with iterators?

???

Copyright

This document has been based on the PEP 204 and is also
placed in the Public Domain.


------------------------

Sincerely yours, Roman A.Suzi
--
- Petrozavodsk - Karelia - Russia - mailto:r...@onego.ru -

Thomas Wouters

unread,
May 8, 2001, 10:17:15 AM5/8/01
to Roman Suzi, pytho...@python.org
On Tue, May 08, 2001 at 11:44:20AM +0400, Roman Suzi wrote:

> What is below is a half-baked proposal for new built-in
> Python operation. If anybody wants to raise this flag
> again and fill gaps, please do so.

> (I have not studied PEP howto much, so probably I missed
> something important.)

Just one thing: you should send it to Barry (ba...@wooz.org) at least if you
want it submitted as a real PEP :)

> I hope the idea of ".." is quite simple: make special syntactic
> form for xrange (range). I am not into C to reference-implement this
> feature, so if anybody could do it...

It's not too hard to do, though the syntax might require some fiddling. (the
'.' is currently eaten by the tokenizer as part of the number.) I could do
it myself, but I'm so busy right now, I think Tim has more time than I do
<0.4 wink>

> The proposed implementation uses new syntactic
> entity to specify range operation, as shown below:

> >>> for i in 1 .. 5:
> ... print i
> 1
> 2
> 3
> 4
> 5

I like, though the endpoint is debatable. Maybe Greg W. wants to do some
usage testing ? :)

> Or in extended form to specify a step:

> >>> for i in (1, 3) .. 5:
> ... print i
> 1
> 3
> 5

I don't like this. If anything, it should be the other way 'round
("1 .. (5, 3)") but even better would be something more obvious, such as

(1 .. 5) % 3

> The new operation ".." generates xrange object
> on by following rule:

I'd suggest it create an Iterator rather than an xrange object. Iterators
are new in the CVS tree, and will be in Python 2.2. Very neat things ;)


> There are no implicit forms of "..", that is, a1 and an must
> be present.

If .. created an iterator, it could be open-ended instead.

> Open issues

How about ranges of longs ? floats ? strings ? How about mixed types ?

--
Thomas Wouters <tho...@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!

Carlos Ribeiro

unread,
May 8, 2001, 6:49:17 PM5/8/01
to Thomas Wouters, Roman Suzi, pytho...@python.org
At 16:17 08/05/01 +0200, Thomas Wouters wrote:
> > >>> for i in 1 .. 5:
> > ... print i
> > 1
> > 2
> > 3
> > 4
> > 5
>
>I like, though the endpoint is debatable. Maybe Greg W. wants to do some
>usage testing ? :)

I think the syntax is clear enough to avoid discussions like
does-it-start-from-one-or-zero? Let the a..b syntax delimit the range
*including* both the minimum and maximum values. BTW it's pretty close to
the range syntax in other languages (such as Pascal, for enumerated
constants and sets).

> > Or in extended form to specify a step:
>
> > >>> for i in (1, 3) .. 5:
> > ... print i
> > 1
> > 3
> > 5
>
>I don't like this. If anything, it should be the other way 'round
>("1 .. (5, 3)") but even better would be something more obvious, such as
>
>(1 .. 5) % 3

This one is a little bit harder. Where did you take the 3 on the example
above? I could not understand the logic of '(1 .. 5) % 3'. I think that the
range operator should specify the step; something like '1 .. 5 % 2' is
clearer in my opinion. The use of '%' as 'step' operator is highly
debatable, though. Why not use any of the characters [!@#$&] ? <wink>

(if we keep going this way '%' is going to be the most overloaded operator
in the history of programming languages :-)

> > The new operation ".." generates xrange object
> > on by following rule:
>
>I'd suggest it create an Iterator rather than an xrange object. Iterators
>are new in the CVS tree, and will be in Python 2.2. Very neat things ;)

Agreed. In fact, xrange could be internally substituted by iterators.

As for other types of range constructors: in Pascal, you can use the syntax
above to construct ranges for enumerated types or sets. The catch is that
only scalar types can be used. This makes sense in Pascal, because the same
syntax is also used to specify sets. In Python, similarly, the same syntax
could be used (in the future) to implement set libraries. OTOH, ranges
built with floats may experience problems caused by the limited precision,
so that's a good reason to avoid it. Fixed point decimals don't suffer from
the same problems, though, and are a better candidate.


Carlos Ribeiro

Greg Ewing

unread,
May 9, 2001, 1:06:56 AM5/9/01
to
If you want to get this considered, you'll have to
make sure your PEP explicitly addresses all the reasons
for the rejection of PEP 204. (That might not be easy,
since the rejection notice attached to PEP 204 is
rather sketchy!)

One thing that comes to mind is the interpretation
of the endpoint. The syntax strongly suggests that the
endpoint is inclusive, as you propose. But this is
not the most useful meaning in Python. Most of the
time, range() is used in constructs such as

for i in range(len(mylist)):

which would become

for i in 0..len(mylist)-1:

The need to include the -1 is a nuisance and
potential source of error.

The alternative, making the endpoint exclusive,
would make the meaning of the .. construct
somewhat unintuitive.

--
Greg Ewing, Computer Science Dept, University of Canterbury,
Christchurch, New Zealand
To get my email address, please visit my web page:
http://www.cosc.canterbury.ac.nz/~greg

Thomas Wouters

unread,
May 9, 2001, 3:22:48 AM5/9/01
to Carlos Ribeiro, Roman Suzi, pytho...@python.org
On Tue, May 08, 2001 at 07:49:17PM -0300, Carlos Ribeiro wrote:

> Agreed. In fact, xrange could be internally substituted by iterators.

No, it could not. xrange(1,10)[3] works, iter(range(1,10))[3] does not:

>>> xrange(1,10)[3]
4
>>> iter(range(1,10))[3]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsubscriptable object
>>>

xrange isn't an iterator, it's a 'generator' (or a 'lazy list'). I agree
that xrange should adhere to the iteration protocol, but making it *just* an
iterator isn't enough.

Roman Suzi

unread,
May 9, 2001, 4:18:19 AM5/9/01
to pytho...@python.org
On Wed, 9 May 2001, Greg Ewing wrote:

>If you want to get this considered, you'll have to
>make sure your PEP explicitly addresses all the reasons

I read them and found that almost all of them are caused
by using slice-like notation.

There are no more reasons to reject ".." than there are
reasons to obsolete range/xrange, because its just
a more newbie-frienly way to write them.


>for the rejection of PEP 204. (That might not be easy,
>since the rejection notice attached to PEP 204 is
>rather sketchy!)

I understand the rejection very well:

":" notation is very overused by the PEP 204.
(makes to much confusion).
IMHO, it's the main reason for Guido to reject it.


>One thing that comes to mind is the interpretation
>of the endpoint. The syntax strongly suggests that the
>endpoint is inclusive, as you propose. But this is
>not the most useful meaning in Python.

The reason under Python incl-excl nature is that
these are intermediate points, needed for slice-operations
to be natural like in:

a[0:0] = [1,2,3]


There is no reason to bring this into ".." notation, because
its different from ":" even visuall and it is more naturally
to use convenient incl-incl ranges.

Most of the
>time, range() is used in constructs such as
>
> for i in range(len(mylist)):

These must be eliminated by use of maps, apply, etc -
by functional style.

>which would become
>
> for i in 0..len(mylist)-1:
>
>The need to include the -1 is a nuisance and
>potential source of error.
>
>The alternative, making the endpoint exclusive,
>would make the meaning of the .. construct
>somewhat unintuitive.

I agree.

The fact, that there will be TWO ways for ranges doesn't
bother me, because the reason to include ".." into
Python is allowing beginners to appreciate more naturally
looking code than range(1,101).

I even think there is a need to rename ".." from range operation
to something other.

Sincerely yours, Roman Suzi
--
_/ Russia _/ Karelia _/ Petrozavodsk _/ r...@onego.ru _/
_/ Wednesday, May 09, 2001 _/ Powered by Linux RedHat 6.2 _/
_/ "Always remember no matter where you go, there you are." _/


Roman Suzi

unread,
May 9, 2001, 4:25:38 AM5/9/01
to Thomas Wouters, pytho...@python.org
On Wed, 9 May 2001, Thomas Wouters wrote:

>On Tue, May 08, 2001 at 07:49:17PM -0300, Carlos Ribeiro wrote:
>
>> Agreed. In fact, xrange could be internally substituted by iterators.
>
>No, it could not. xrange(1,10)[3] works, iter(range(1,10))[3] does not:
>
>>>> xrange(1,10)[3]
>4
>>>> iter(range(1,10))[3]
>Traceback (most recent call last):
> File "<stdin>", line 1, in ?
>TypeError: unsubscriptable object
>>>>
>
>xrange isn't an iterator, it's a 'generator' (or a 'lazy list'). I agree
>that xrange should adhere to the iteration protocol, but making it *just* an
>iterator isn't enough.

I think, ".." will be just another way to write xrange.
If it ever will be an iterator - so will be "..".

Or it could be some yet-to-implement irange, which
can be read as "inclusive range" or "iterator-creating range"
-- this must not stop from proposing ".." notation now.

This small feature will make Python's for loops much
friendlier to beginners.

I do not fear

for i in 0..len(mylist)-1

because this is _explicit_ writing of the fact mylist
is indexed from 0. If there will be errors, they will
cause IndexErrors and not some subtle logical errors.

Alex Martelli

unread,
May 9, 2001, 4:59:46 AM5/9/01
to
"Greg Ewing" <s...@my.signature> wrote in message
news:3AF8D070...@my.signature...
[snip]

> The alternative, making the endpoint exclusive,
> would make the meaning of the .. construct
> somewhat unintuitive.


for x in seq[a:b]:
print x


versus


for i in a..b:
print seq[i]


My own intuition would expect the same behavior
from these two loops. I would consider it VERY
unintuitive to have them behave differently!!!

Maybe this should be accepted and reinforced
with a different syntax for the range, e.g.

for i in [a:b]:
print seq[i]

with the existing brackets-and-colons tokens
in lieu of the new proposed '..' token. Now
the fact that b is excluded, just as in s[a:b],
should perhaps be even more obvious...?


Alex

Duncan Booth

unread,
May 9, 2001, 6:22:53 AM5/9/01
to
Carlos Ribeiro <crib...@mail.inet.com.br> wrote in
<mailman.989362093...@python.org>:

>>(1 .. 5) % 3
>
> This one is a little bit harder. Where did you take the 3 on the
> example above? I could not understand the logic of '(1 .. 5) % 3'. I
> think that the range operator should specify the step; something like
> '1 .. 5 % 2' is clearer in my opinion. The use of '%' as 'step'
> operator is highly debatable, though. Why not use any of the characters
> [!@#$&] ? <wink>
>

Why not add a 'step' method to iterators and sequence types?
step(self, step, start=0)
Returns a new iterator or sequence containing every 'step'
value from index 'start' in the original sequence.
For iterators this would return a new iterator, for sequences it would
return a new sequence. If you want a step iterator from a sequence you just
have to do: iter(sequence).step(n)

So:

>>> range(1, 11).step(2)
[1, 3, 5, 7, 9]
>>> (1..10).step(2)
<some iterator type returning 1, 3, 5, 7, 9 successively>
>>> range(1, 11).step(2, 1)
[2, 4, 6, 8, 10]
>>> lst = range(1, 11)
>>> zip(lst.step(2), lst.step(2, 1))
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]

--
Duncan Booth dun...@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?

Alex Martelli

unread,
May 9, 2001, 6:01:16 AM5/9/01
to
"Roman Suzi" <r...@onego.ru> wrote in message
news:mailman.989396953...@python.org...
...

> I do not fear
>
> for i in 0..len(mylist)-1
>
> because this is _explicit_ writing of the fact mylist
> is indexed from 0. If there will be errors, they will
> cause IndexErrors and not some subtle logical errors.

I disagree. Inclusive-lower-bound, exclusive-upper-bound
is a VERY important and useful idiom, which we should
strive to make as widespread as we possibly can: by the
very fact of being invariably used everywhere lower and
upper bounds are specified, it helps a LOT against
off-by-one errors! I first saw it explained in Koenig's
excellent "C traps and pitfalls" book, by the way.

Python does it pretty well today:

for item in seq[lower:upper]:
print item

and

for index in range(lower,upper):
print seq[index]

behave the same way, just as they should. If instead:

for index in lower..upper:
print seq[index]

did behave differently, I would could that as a very
serious inconsistency in the language. I believe it
would induce many off-by-one errors in apparently
unrelated situations, such as slices, in newbies, as
well as being a nasty tripwire for experienced users.


Alex

Alex Martelli

unread,
May 9, 2001, 6:23:56 AM5/9/01
to
"Roman Suzi" <r...@onego.ru> wrote in message
news:mailman.989396968...@python.org...
...

> >One thing that comes to mind is the interpretation
> >of the endpoint. The syntax strongly suggests that the
> >endpoint is inclusive, as you propose. But this is
> >not the most useful meaning in Python.
>
> The reason under Python incl-excl nature is that
> these are intermediate points, needed for slice-operations
> to be natural like in:
>
> a[0:0] = [1,2,3]

That is far from being the only reason!

> There is no reason to bring this into ".." notation, because
> its different from ":" even visuall and it is more naturally
> to use convenient incl-incl ranges.

"convenience" is probably the excuse brought for the worst
pieces of software design today, although the older one of
"optimization" is still going strong.

Upper-bound-excluded ranges are in fact more convenient, and
help avoid off-by-one errors. Having DIFFERENT behavior
between seq[a:b] and [seq[x] for x in a..b] would, moreover,
be PARTICULARLY horrid.


> >time, range() is used in constructs such as
> >
> > for i in range(len(mylist)):
>
> These must be eliminated by use of maps, apply, etc -
> by functional style.

s/must/may often/. Iterating over a range of indices
will remain an important idiom even when a newbie has
fully digested map and apply. For example, often we
need to operate on items in a sequence depending on
the item that comes immediately before or after. To
say that the approach of zipping the sequence to its
"shifted" copy "must", or even "should", eliminate the
simple and obvious approach of index-loops smacks of
very substantial hubris.

For example, let's say we need the sequence of all
characters that come right after a '!' in string s.


Zip-approach:

def afterbang1(s):
result = []
for previous, thisone in zip(s, s[1:]):
if previous == '!':
result.append(thisone)
return result

versus index-approach:

def afterbang2(s):
result = []
for i in range(1,len(s)):
if s[i-1] == '!':
result.append(s[i])
return result

versus keep-state approach:

def afterbang3(s):
result = []
previous = s[0]
for c in s[1:]:
if previous == '!':
result.append(c)
previous = c
return result

versus "map, apply, etc" approach:

def afterbang4(s):
return map(lambda x,y: y,
filter(lambda x,y: x=='!',
map(None, s[:-1], s[1:])))


Personally, I find afterbang2 clearest, and
therefore best. If concision is a goal, the
first two approaches can easily be rewritten
as list comprehensions, of course:

Zip-approach with LC:

def afterbang1_LC(s):
return [ thisone
for previous, thisone in zip(s, s[1:])
if previous == '!' ]

versus index-approach with LC:

def afterbang2_LC(s):
return [ s[i]
for i in range(1, len(s))
if s[i-1] == '!' ]

Again, it's a subtle matter of taste between
these two, but I think the second one is better.


I definitely wouldn't mind having a
for i in 1..len(s)
alternative to use in afterbang2 and 2_LC,
but I'd never consider having to use
for i in 1..len(s)+1
as even remotely approaching acceptability.


> >The alternative, making the endpoint exclusive,
> >would make the meaning of the .. construct
> >somewhat unintuitive.
>
> I agree.

I don't.


> The fact, that there will be TWO ways for ranges doesn't
> bother me, because the reason to include ".." into
> Python is allowing beginners to appreciate more naturally
> looking code than range(1,101).

Getting beginners used to inclusive-upper-end idioms
and then having them trip over exclusive-upper-end
ones elsewhere later is NOT doing them any favour.


Alex

Carlos Ribeiro

unread,
May 9, 2001, 9:14:08 AM5/9/01
to Alex Martelli, pytho...@python.org
At 12:23 09/05/01 +0200, Alex Martelli wrote:
>Getting beginners used to inclusive-upper-end idioms
>and then having them trip over exclusive-upper-end
>ones elsewhere later is NOT doing them any favour.

Ok, I'm in brainstorm mode. You're warned :-) Some weird ideas are just
popping out of my mind:

1) Have both ':' and '..' as range operators. ':' excludes the last
element, '..' includes it. This is a very simple rule-of-thumb. A beginner
may be confused, but it's not something hard to learn.

2) Force the construct to be specified inside brackets or parenthesis,
pretty much like list comprehensions.

3) If (2) is approved, then the step operator becomes a natural extension
of the list comprehension syntax:

>>> [1..5 step 2]
[1,3,5]
>>> [1:5 step 2]
[1,3]

It's clear, readable and unambiguous.


Carlos Ribeiro

Alex Martelli

unread,
May 9, 2001, 9:15:54 AM5/9/01
to pytho...@python.org, Carlos Ribeiro
"Carlos Ribeiro" <crib...@mail.inet.com.br> writes:
> At 12:23 09/05/01 +0200, Alex Martelli wrote:
> >Getting beginners used to inclusive-upper-end idioms
> >and then having them trip over exclusive-upper-end
> >ones elsewhere later is NOT doing them any favour.
>
> Ok, I'm in brainstorm mode. You're warned :-) Some weird ideas are just
> popping out of my mind:
>
> 1) Have both ':' and '..' as range operators. ':' excludes the last
> element, '..' includes it. This is a very simple rule-of-thumb. A beginner
> may be confused, but it's not something hard to learn.

I think it might be -- I see no graphical suggestion of the
behavior differences.

> 2) Force the construct to be specified inside brackets or parenthesis,
> pretty much like list comprehensions.

I like the ideas of brackets for that.


for i in [a:b]

just looks so neat...:-).

> 3) If (2) is approved, then the step operator becomes a natural extension
> of the list comprehension syntax:
>
> >>> [1..5 step 2]
> [1,3,5]
> >>> [1:5 step 2]
> [1,3]
>
> It's clear, readable and unambiguous.

Sure does. I wonder if 'step' would have to become a keyword here
(presumably a no-go) or if it could be "fudged" the way non-keyword
"as" was added to import and from statements.


Alex

Thomas Heller

unread,
May 9, 2001, 10:12:56 AM5/9/01
to
> > At 12:23 09/05/01 +0200, Alex Martelli wrote:
> > >Getting beginners used to inclusive-upper-end idioms
> > >and then having them trip over exclusive-upper-end
> > >ones elsewhere later is NOT doing them any favour.
> >
> > Ok, I'm in brainstorm mode. You're warned :-) Some weird ideas are just
> > popping out of my mind:
> >
for i in [0:10):
print i

for i in [0:10]:
print i

Thomas

Roman Suzi

unread,
May 9, 2001, 10:30:48 AM5/9/01
to pytho...@python.org
On Wed, 9 May 2001, Carlos Ribeiro wrote:

>At 12:23 09/05/01 +0200, Alex Martelli wrote:
>>Getting beginners used to inclusive-upper-end idioms
>>and then having them trip over exclusive-upper-end
>>ones elsewhere later is NOT doing them any favour.
>
>Ok, I'm in brainstorm mode. You're warned :-) Some weird ideas are just
>popping out of my mind:
>

>1) Have both ':' and '..' as range operators. ':' excludes the last
>element, '..' includes it. This is a very simple rule-of-thumb. A beginner
>may be confused, but it's not something hard to learn.

I agree.

>
>2) Force the construct to be specified inside brackets or parenthesis,
>pretty much like list comprehensions.

This is what rejected PEP 204 is about...

>3) If (2) is approved, then the step operator becomes a natural extension
>of the list comprehension syntax:
>
> >>> [1..5 step 2]
>[1,3,5]
> >>> [1:5 step 2]
>[1,3]
>
>It's clear, readable and unambiguous.

Well, I do not pretend (1, 2) .. 5 is the only way.
But "a .. b step c" is too... verbose.

>Carlos Ribeiro

Bjorn Pettersen

unread,
May 9, 2001, 11:52:46 AM5/9/01
to pytho...@python.org
> From: Thomas Heller [mailto:thomas...@ion-tof.com]

>
> > > At 12:23 09/05/01 +0200, Alex Martelli wrote:
> > > >Getting beginners used to inclusive-upper-end idioms
> > > >and then having them trip over exclusive-upper-end
> > > >ones elsewhere later is NOT doing them any favour.
> > >
> > > Ok, I'm in brainstorm mode. You're warned :-) Some weird
> ideas are just
> > > popping out of my mind:
> > >
> for i in [0:10):
> print i
>
> for i in [0:10]:
> print i
>
> Thomas

If all we want to do is get rid of

for i in range(len(seq)):
...

why not overload range so it can take a sequence directly:

for i in range(seq):
...

If we really want range literals (which I don't see as particularly useful
outside this application although I'm happy to be proven wrong <wink>), we
can't use x:y since Guido has allready nixed it, and we shouldn't use x..y
since the established meaning interfers with common usage leading to
unappealing constructs like 0..len(seq)-1. We could certainly come up with
other syntax, e.g. x -> y meaning from x up to, but not including, y:

for i in 0 -> len(seq):
...

I still favor overloading range though...

-- bjorn

Terry Reedy

unread,
May 9, 2001, 12:01:13 PM5/9/01
to

"Thomas Heller" <thomas...@ion-tof.com> wrote in message
news:9dbj8j$h83n5$1...@ID-59885.news.dfncis.de...

> > > Ok, I'm in brainstorm mode. You're warned :-) Some weird ideas are
just
> > > popping out of my mind:
> > >
> for i in [0:10):
> print i
>
> for i in [0:10]:
> print i

Since this is standard math notation for ranges, with : substituted for ,
to avoid syntax conflict, I like it the best of all proposals in this
thread. A step value, is present, could go either in middle or end.

Carlos Ribeiro

unread,
May 9, 2001, 12:05:38 PM5/9/01
to Bjorn Pettersen, pytho...@python.org
At 09:52 09/05/01 -0600, Bjorn Pettersen wrote:
>If we really want range literals (which I don't see as particularly useful
>outside this application although I'm happy to be proven wrong <wink>) ...

I would really like to perform set operations in Python. Some good
libraries already provide support for this (kjBuckets comes to mind). The
a..b syntax is a nice way to specify arbitrary set constants, such as in:

if some_number in [1..3,7..9]:
do_something()

There are several uses for constructs like the one above. I keep thinking
that '..' is clearly inclusive, so why not give it a try?


Carlos Ribeiro

Rainer Deyke

unread,
May 9, 2001, 1:27:49 PM5/9/01
to
"Bjorn Pettersen" <BPett...@NAREX.com> wrote in message
news:mailman.989423654...@python.org...

> for i in 0 -> len(seq):
> ...
>
> I still favor overloading range though...

I favor leaving Python as-is, since this entire thread is about solving a
non-problem. If you want a shorter way of writing 'range(len(x))', you can
always write your own function. If there is really a need of such a
function in '__builtin__', I would prefer that it have a new name. How
about 'indexes'?


--
Rainer Deyke (ro...@rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor


Roman Suzi

unread,
May 9, 2001, 12:55:11 PM5/9/01
to pytho...@python.org

Please, recall the main reason for the new feature:

- to allow beginners learn loops BEFORE they learn
lists and functions (which are needed now to explain
for-loop).

Even recursion could be explained without lists in Python,
why for-loops need this prerequisite?

It is not too expensive to write range(a,b,c) or
something similar, but cp4e needs cleaner way to do for loops.

If not ".." syntax, then any other, but with EXPLICIT
mentioning of the including/excluding nature of
ranges.

eg

for i from 1 to 10

for i from 1 before 11

for j from 1 to 100 step 2


-- these could be also used in list comprehensions consistently:

[i for i from 1 to 10]

*

But our discussion showed that there is probably no
much need in pushing ".." any more... :-(
because I see ".." as an only-for-novice feature
and we (who discuss) are no novices to judge...

Andrew Dalke

unread,
May 9, 2001, 2:20:56 PM5/9/01
to

Carlos Ribeiro wrote:
>The a..b syntax is a nice way to specify arbitrary set
>constants, such as in:
>
>if some_number in [1..3,7..9]:
> do_something()

Something like that can already be done without introducing
new syntax, as in

>>> import types
>>> class Set:
... def __getitem__(self, terms):
... data = []
... for term in terms:
... if type(term) == types.SliceType:
... for x in range(term.start, term.stop):
... data.append(x)
... else:
... data.append(term)
... return data
...
>>>
>>> Set = Set()
>>> Set[1:3, 7:9]
[1, 2, 7, 8]
>>> Set[1, 4:10]
[1, 4, 5, 6, 7, 8, 9]
>>>

Andrew
da...@acm.org

Douglas Alan

unread,
May 9, 2001, 2:25:40 PM5/9/01
to
Why don't we just nip this creeping-featurism in the bud and just say
"no" to a new range syntax.

(And if it were to exist, which it shouldn't, Alex is right that it
*has* to be a semi-closed interval. Anything else would be an
abomination.)

|>oug

Fredrik Lundh

unread,
May 9, 2001, 3:23:46 PM5/9/01
to
Roman Suzi wrote:
> Please, recall the main reason for the new feature:
>
> - to allow beginners learn loops BEFORE they learn
> lists and functions (which are needed now to explain
> for-loop).
>
> Even recursion could be explained without lists in Python,
> why for-loops need this prerequisite?

done much python training lately, or are you just making
things up as you go?

(in my experience, you don't have to understand much
about functions and lists to learn how to *use* range in
simple for-in loops...)

Cheers /F


Denys Duchier

unread,
May 9, 2001, 3:51:03 PM5/9/01
to
"Alex Martelli" <ale...@yahoo.com> writes:

> I like the ideas of brackets for that.
> for i in [a:b]
> just looks so neat...:-).

That was the subject of PEP 204 (Range Literals) which was rejected.
I don't know why. (the stated open issues should simply all be
answered with: "no magic!").

It seems to me that it would be rather neat to extend the list
comprehension idea to be able to create an iterator rather than a
list. I shudder at the idea of proposing syntax for that, but using
[| ... |] instead of [ ... ] might work.

Now excuse me while I run for cover... :-)

--
Dr. Denys Duchier Denys....@ps.uni-sb.de
Forschungsbereich Programmiersysteme (Programming Systems Lab)
Universitaet des Saarlandes, Geb. 45 http://www.ps.uni-sb.de/~duchier
Postfach 15 11 50 Phone: +49 681 302 5618
66041 Saarbruecken, Germany Fax: +49 681 302 5615

Walter Moreira

unread,
May 9, 2001, 3:10:39 PM5/9/01
to pytho...@python.org
On Wed, May 09, 2001 at 09:52:46AM -0600, Bjorn Pettersen wrote:
> If all we want to do is get rid of
>
> for i in range(len(seq)):
> ...
>
> why not overload range so it can take a sequence directly:
>
> for i in range(seq):
> ...

Isn't more pythonic the recipe (i think it is from Alex):

for i, a in Indexed(seq):
...

where indexed is just:

class Indexed:
def __init__(self, seq):
self.seq = seq
def __getitem__(self, i):
return i, self.seq[i]

? Do we really need syntatic changes (..) and semantic changes also? Doesn't
things like '..' make the language more difficult to learn for begginners?

The reference manual must be bigger and bigger with each addition of this
kind. Other changes, like the elimination of the type/class differences make
the manual smaller. I think these are the things to be focused on.

Regards:
Walter

--
--------------
Walter Moreira <> Centro de Matematica <> Universidad de la Republica
email: wal...@cmat.edu.uy <> HomePage: http://www.cmat.edu.uy/~walterm
+-----------------------------------------------------
/OD\_ | Contrary to popular belief, Unix is user friendly.
O o . |_o_o_) | It just happens to be very selective about who its
| friends are. -- Kyle Hearn
--+--

Fredrik Lundh

unread,
May 9, 2001, 4:43:16 PM5/9/01
to
Douglas Alan wrote:
> Why don't we just nip this creeping-featurism in the bud and just say
> "no" to a new range syntax.

like we did with those pesky macros, you mean?

Cheers /F


Douglas Alan

unread,
May 9, 2001, 5:56:27 PM5/9/01
to
"Fredrik Lundh" <fre...@pythonware.com> writes:

> > Why don't we just nip this creeping-featurism in the bud and just say
> > "no" to a new range syntax.

> like we did with those pesky macros, you mean?

Yup, except that I think "we" should think more carefully about the
difference between powerful abstraction mechanisms and
creeping-featurism. The former helps prevent the latter.

(Besides, I never lobbied for Python to include macros. I only stated
that it would be a better language if it had them. But sometimes
better is worse.)

|>oug

Douglas Alan

unread,
May 9, 2001, 7:32:49 PM5/9/01
to
Speaking of creeping-featurism, how come we have list comprehension,
but not tuple comprehension? Seems inconsistent to me.

|>oug

Ben Hutchings

unread,
May 9, 2001, 8:27:22 PM5/9/01
to
Douglas Alan <nes...@mit.edu> writes:

> Speaking of creeping-featurism, how come we have list comprehension,
> but not tuple comprehension? Seems inconsistent to me.

A list contains a variable number of homogeneous values, e.g. the
lines of a file. Lists are like arrays in other languages. A tuple
contains a fixed number of heterogeneous values where each element has
a distinct meaning e.g. (year, month, day) for a date. Tuples are
like data structures or product types in other languages, except that
their types and fields are nameless. Comprehensions work with a
variable number of homogeneous values, so they produce lists.

--
Any opinions expressed are my own and not necessarily those of Roundpoint.

Joshua Marshall

unread,
May 9, 2001, 9:00:51 PM5/9/01
to
Ben Hutchings <ben.hu...@roundpoint.com> wrote:

> A list contains a variable number of homogeneous values, e.g. the
> lines of a file.

Homogeneousness isn't required, though I'd expect it's how they're
often used.

Delaney, Timothy

unread,
May 9, 2001, 8:20:00 PM5/9/01
to Roman Suzi, pytho...@python.org
> ":" notation is very overused by the PEP 204.
> (makes to much confusion).
> IMHO, it's the main reason for Guido to reject it.
>
>
> >One thing that comes to mind is the interpretation
> >of the endpoint. The syntax strongly suggests that the
> >endpoint is inclusive, as you propose. But this is
> >not the most useful meaning in Python.
>
> The reason under Python incl-excl nature is that
> these are intermediate points, needed for slice-operations
> to be natural like in:
>
> a[0:0] = [1,2,3]
>
>
> There is no reason to bring this into ".." notation, because
> its different from ":" even visuall and it is more naturally
> to use convenient incl-incl ranges.

Well, there would be a simple way to make ranges that conformed to both. Use
the mathematical notation for describing inclusive and exclusive bounds
(although it would be using '..' instead of ',').

If I remember correctly ...

[0..10] - range is 0 to 10
[0..10) - range is 0 to 9
(0..10] - range is 1 to 10
(0..10) - range is 1 to 9

There - everyone is happy, and an unadorned 0..10 is an error.

This has the advantage of looking more like a sequence as well.

It also has the disadvantage that it may not be immediately obvious to
someone what the range is - '(' and '[' aren't *that* dissimilar when right
near each other.

The other consideration is how this would work with steps. Perhaps
overloading ':' here would work, since 0..10 unadorned would be invalid ...

[0..10:3] - range is 0 to 10, step 3
(10..0:-2] - range is 9 to 0, step -2

Anyway, I'm sure there are lots of objections to this, but I'd like to hear
them :)

Tim Delaney

Douglas Alan

unread,
May 9, 2001, 11:33:26 PM5/9/01
to
Ben Hutchings <ben.hu...@roundpoint.com> writes:

> Douglas Alan <nes...@mit.edu> writes:

> > Speaking of creeping-featurism, how come we have list comprehension,
> > but not tuple comprehension? Seems inconsistent to me.

> A list contains a variable number of homogeneous values, e.g. the
> lines of a file. Lists are like arrays in other languages. A tuple
> contains a fixed number of heterogeneous values where each element
> has a distinct meaning e.g. (year, month, day) for a date.

I think you have some other language in mind, rather than Python. In
Python, the only semantic difference between a list and a tuple is
that a tuple is immutable.

> Tuples are like data structures or product types in other languages,
> except that their types and fields are nameless. Comprehensions
> work with a variable number of homogeneous values, so they produce
> lists.

filter() on a tuple returns a tuple. The length of the tuple cannot
be known in advance. map(), on the other hand, always returns a list.
But map can take multiple sequence arguments, so it wouldn't always be
obvious to know which type of sequence to duplicate. I suppose the
same is true for comprehension. But, it seems to me that Python could
allow

(x*2 for x in t)

to make a tuple as easily as it allows

[x*2 for x in l]

to make a list.

|>oug

Greg Ewing

unread,
May 10, 2001, 12:11:38 AM5/10/01
to
Douglas Alan wrote:
>
> Speaking of creeping-featurism, how come we have list comprehension,
> but not tuple comprehension?

Who says we don't?

tuple([2*i for i in [1,2,3]])

:-)

--
Greg Ewing, Computer Science Dept, University of Canterbury,
Christchurch, New Zealand
To get my email address, please visit my web page:
http://www.cosc.canterbury.ac.nz/~greg

Greg Ewing

unread,
May 10, 2001, 12:15:14 AM5/10/01
to
Alex Martelli wrote:
>
> Maybe this should be accepted and reinforced
> with a different syntax for the range, e.g.
>
> for i in [a:b]:

But that's exactly what PEP 204 proposed, and
Guido rejected it.

(The PEPs are supposed to record such decisions
so that these discussions don't keep recurring.
But that only works if people read the PEPs. :-)
Maybe we need a bot that posts all the rejected
PEPs to c.l.py every month? :-) :-)

Greg Ewing

unread,
May 10, 2001, 12:37:18 AM5/10/01
to
Roman Suzi wrote:
>
> Please, recall the main reason for the new feature:
>
> - to allow beginners learn loops BEFORE they learn
> lists and functions

I don't see anything wrong with learning about
lists before for-loops. Playing with lists is
much more fun than just playing with numbers
(which non-mathematically-inclined people may
find boring).

And functions don't come into it at all,
either way.

> But our discussion showed that there is probably no
> much need in pushing ".." any more... :-(
> because I see ".." as an only-for-novice feature
> and we (who discuss) are no novices to judge...

More importantly, I don't think there should be
any syntax that is there *just* for novices. A
piece of syntax needs to earn its keep much better
than that before it's worth keeping around.

Roman Suzi

unread,
May 9, 2001, 2:20:29 PM5/9/01
to pytho...@python.org
On Wed, 9 May 2001, Rainer Deyke wrote:

>"Bjorn Pettersen" <BPett...@NAREX.com> wrote in message
>news:mailman.989423654...@python.org...
>> for i in 0 -> len(seq):
>> ...
>>
>> I still favor overloading range though...
>
>I favor leaving Python as-is, since this entire thread is about solving a
>non-problem.

The problem is not to make range(len(seq)) shorter, but
to make for loop easier to learn:

right now FUNCTIONS and LISTS are needed to understand
for loop. (Even recursion is "easier" with just FUNCTIONS
to know ;-)

So, I started the thread to:

1. Discuss if the raised problem is "no problem"
2. If the 1. is not true, to discuss syntactic solution.

We seem to drift to no. 2 without questioning no. 1.

>If you want a shorter way of writing 'range(len(x))', you can
>always write your own function. If there is really a need of such a
>function in '__builtin__', I would prefer that it have a new name. How
>about 'indexes'?

Sincerely yours, Roman Suzi

Steve Holden

unread,
May 9, 2001, 10:00:09 PM5/9/01
to
"Delaney, Timothy" <tdel...@avaya.com> wrote ...
[ ... ]

> Well, there would be a simple way to make ranges that conformed to both.
Use
> the mathematical notation for describing inclusive and exclusive bounds
> (although it would be using '..' instead of ',').
>
> If I remember correctly ...
>
> [0..10] - range is 0 to 10
> [0..10) - range is 0 to 9
> (0..10] - range is 1 to 10
> (0..10) - range is 1 to 9
>
Correct me if I'm wrong, but don't the concepts of open and closed intervals
belong to analysis and not discrete mathematics -- in other words, they
apply to infinite sets but not finite ones. An open interval (x,y) is the
set of all numbers strictly greater than x and strictly less than y.
Dedekind will be turning in his grave...

This proposed notation (and you aren't the first to propose it) would be
bizarrely misunderstood by newcomers. I certainly don't want to have to
explain that the same object can be described in four different ways, and
suggest when [1..9] is more appropriate than (0..10) is more appropriate
than [1..10) is more appropriate than (0..9].

So, why have four representations for the same thing?

there-should-be-one-obvious-way-to-do-it-ly y'rs - steve

Steve Holden

unread,
May 10, 2001, 1:29:04 AM5/10/01
to
"Roman Suzi" <r...@onego.ru> wrote in ...

> On Wed, 9 May 2001, Rainer Deyke wrote:
>
[ ... ]

>
> right now FUNCTIONS and LISTS are needed to understand
> for loop. (Even recursion is "easier" with just FUNCTIONS
> to know ;-)
>
I would argue you could teach for loops by using existing lists without any
function usage at all, as in (for example):

for dir in sys.path:
print dir

regards
STeve


Roman Suzi

unread,
May 10, 2001, 1:31:31 AM5/10/01
to pytho...@python.org
On Wed, 9 May 2001, Fredrik Lundh wrote:

> Roman Suzi wrote:
> > Please, recall the main reason for the new feature:
> >
> > - to allow beginners learn loops BEFORE they learn

> > lists and functions (which are needed now to explain
> > for-loop).
> >
> > Even recursion could be explained without lists in Python,
> > why for-loops need this prerequisite?
>
> done much python training lately, or are you just making

Yes. I taught programming classes a year ago.
That is where I had some trouble with for-loops.

> things up as you go?
>
> (in my experience, you don't have to understand much
> about functions and lists to learn how to *use* range in
> simple for-in loops...)
>
> Cheers /F


Sincerely yours, Roman A.Suzi
--
- Petrozavodsk - Karelia - Russia - mailto:r...@onego.ru -

Delaney, Timothy

unread,
May 10, 2001, 2:07:56 AM5/10/01
to pytho...@python.org
Firstly, I don't personally feel there is a need for a new notation, but it
is fun to work out what would work best were we indeed to have one ...

> > Well, there would be a simple way to make ranges that
> conformed to both.
> Use
> > the mathematical notation for describing inclusive and
> exclusive bounds
> > (although it would be using '..' instead of ',').
> >
> > If I remember correctly ...
> >
> > [0..10] - range is 0 to 10
> > [0..10) - range is 0 to 9
> > (0..10] - range is 1 to 10
> > (0..10) - range is 1 to 9
> >
> Correct me if I'm wrong, but don't the concepts of open and
> closed intervals
> belong to analysis and not discrete mathematics -- in other
> words, they
> apply to infinite sets but not finite ones. An open interval
> (x,y) is the
> set of all numbers strictly greater than x and strictly less than y.
> Dedekind will be turning in his grave...

Well, there are *no* infinite sets in computing, so it's not generally
applicable here (the largest long integer in Python for example must be
bound by the amount of memory available to the Python process).

That may well be true (been a few years since I've done any formal maths
work/study), however it is fine system (which is an infinite set) 9 is the
greatest integer strictly less than 10.

It's is perfectly valid to define the set you are using - this notation
would only be valid for the set of integers (including long integers
naturally).

> This proposed notation (and you aren't the first to propose
> it) would be
> bizarrely misunderstood by newcomers. I certainly don't want
> to have to
> explain that the same object can be described in four
> different ways, and
> suggest when [1..9] is more appropriate than (0..10) is more
> appropriate
> than [1..10) is more appropriate than (0..9].
>
> So, why have four representations for the same thing?

Again, I personally agree ... you may have noticed my comment "There -
everyone is happy" ... ;) OTOH, I think inclusive lower-bound, optional
inclusive upper bound i.e. [] and [) would be useful. Having optional
exclusive lower bound was just a bit of fun.

Also, remember that it is quite possible to create a range counting down ...
in some cases I could see exclusive lower bound, inclusive upper bound being
useful (except that's really ex upper, in lower, but in reverse ...).

Tim Delaney

Fredrik Lundh

unread,
May 10, 2001, 3:11:44 AM5/10/01
to
Roman Suzi wrote:
>
> > done much python training lately, or are you just making
>
> Yes. I taught programming classes a year ago.
> That is where I had some trouble with for-loops.

and you don't think you can adjust the training material to cover
lists and functions briefly (from a use, don't create perspective)
before going into details about what for-in really does?

adding inconsistencies to the language to work around a problem
someone once had when explaining the current situation doesn't
sound that appealing...

Cheers /F


Alex Martelli

unread,
May 10, 2001, 4:48:04 AM5/10/01
to
"Roman Suzi" <r...@onego.ru> wrote in message
news:mailman.989472800...@python.org...
...

> > > Even recursion could be explained without lists in Python,
> > > why for-loops need this prerequisite?
> >
> > done much python training lately, or are you just making
>
> Yes. I taught programming classes a year ago.
> That is where I had some trouble with for-loops.

Personally, I've found that for-loops can easily
be taught without having introduced lists yet,
because they work on ANY sequence -- and a datatype
you will surely have introduced VERY early in any
Python course is "string"! A string is a sequence.
This is of limited (though non-null) usefulness in
most Python use, but it SURE comes in handy when
teaching Python to a totally-raw beginner...:

"""
For example, let's print the vowels, only, from
the string the user has introduced. This is easy
because we can look at any string one character
at a time with the for statement.

astring = raw_input("Please enter a string: ")
print "Vowels:",
nvowels = 0
for c in astring:
if c in 'aeiouAEIOU':
print c,
nvowels = nvowels + 1
print
print nvowels,"vowels in total"
if nvowels:
print "The last vowel was",c
"""

then you can go on to explain break, for/else,
and so on, all based on this simple toy example
about looping character by character on a string.

I do think one probably needs to have introduced
raw_input, strings, integers, assignment,
print, and if, before loops can fruitfully be
presented to a raw beginner. But having some
nice special syntax for range literals would not
alter that, it seems to me. Lists, if you wish,
can still come later, anyway.


Alex

Alex Martelli

unread,
May 10, 2001, 6:32:52 AM5/10/01
to
"Douglas Alan" <nes...@mit.edu> wrote in message
news:lc1ypym...@gaffa.mit.edu...
...

> (Besides, I never lobbied for Python to include macros. I only stated
> that it would be a better language if it had them. But sometimes
> better is worse.)

Didn't you write "Python should have procedural macros like Lisp."
(on 2001-04-16 14:20:05 PST -- google doesn't make it easy to give
other and more precise message identification)?

"Lobbying" no doubt connotes much more and better organized effort
than just posting netnews messages. But you didn't just state that
Python would be a better language if it had macros: you did write it
*SHOULD* have them (nor did I ever read anything from you to the
tone of "sorry, I was wrong, it SHOULDN'T have them" -- lots that
might be interpreted as attempts at backing off without actually
doing so, but never any apology or retraction).


Just to clarify by analogy and example: I opine, for example, that
Python would be a (marginally) better language if it didn't have
`expression` as a shorthand for repr(expression) -- it's one extra
(little) piece of syntactic baggage which IMHO is not "carrying
its weight". But from this opinion does not follow that Python
*shouldn't* have `expression` -- that would be quite a stronger
assertion (personally, there is exactly one construct in Python
today of which I feel I could assert Python "shouldn't have it").


Alex

Roman Suzi

unread,
May 10, 2001, 7:38:38 AM5/10/01
to Fredrik Lundh, pytho...@python.org

There is no demand for syntactically supported ranges?

Roman Suzi

unread,
May 10, 2001, 7:41:21 AM5/10/01
to Alex Martelli, pytho...@python.org
On Thu, 10 May 2001, Alex Martelli wrote:

> "Roman Suzi" <r...@onego.ru> wrote in message
> news:mailman.989472800...@python.org...
> ...
> > > > Even recursion could be explained without lists in Python,
> > > > why for-loops need this prerequisite?
> > >
> > > done much python training lately, or are you just making
> >
> > Yes. I taught programming classes a year ago.
> > That is where I had some trouble with for-loops.
>
> Personally, I've found that for-loops can easily
> be taught without having introduced lists yet,
> because they work on ANY sequence -- and a datatype
> you will surely have introduced VERY early in any
> Python course is "string"! A string is a sequence.
> This is of limited (though non-null) usefulness in
> most Python use, but it SURE comes in handy when
> teaching Python to a totally-raw beginner...:

Thank you Alex! This idea have not occured to me
(about strings as sequences instead of lists).

Carlos Ribeiro

unread,
May 10, 2001, 8:11:10 AM5/10/01
to Roman Suzi, Fredrik Lundh, pytho...@python.org
At 15:38 10/05/01 +0400, Roman Suzi wrote:
>There is no demand for syntactically supported ranges?

Yes, I think it would be a nice addition, and I'm sure we're not alone -
many people on the group contributed with ideas on this topic. While I
understand that there are some issues with the proposal - including or
excluding the upper limit, using braces to delimit the range, or how to
specify the step operator - I believe that the concerns are mostly in the
reaction-to-change field.

So, if we can propose a new syntax that:

- is clear for both novices and experienced Python programmers
- does not break anyone's code
- is consistent with related features (slicing and list comprehensions)

... there will be no real reason not to make it.


p.s. I was one of the guys that wrote about 'creeping featurism' a few
months ago. I don't think that it is a good idea, and many PEPs were really
weird. Now, this seems to be a very simple addition to me, because we can
meet the three criteria above. I'm happy to be proved wrong, but please,
let's talk about facts, not emotions, ok?


Carlos Ribeiro

Rainer Deyke

unread,
May 10, 2001, 11:19:26 AM5/10/01
to
"Carlos Ribeiro" <crib...@mail.inet.com.br> wrote in message
news:mailman.989496615...@python.org...

> So, if we can propose a new syntax that:
>
> - is clear for both novices and experienced Python programmers
> - does not break anyone's code
> - is consistent with related features (slicing and list comprehensions)
>
> ... there will be no real reason not to make it.

Only if you don't value simplicity. If this is the case, why are you using
Python at all?


--
Rainer Deyke (ro...@rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor


Rainer Deyke

unread,
May 10, 2001, 11:19:25 AM5/10/01
to
"Roman Suzi" <r...@onego.ru> wrote in message
news:mailman.989469107...@python.org...

> On Wed, 9 May 2001, Rainer Deyke wrote:
> The problem is not to make range(len(seq)) shorter, but
> to make for loop easier to learn:
>
> right now FUNCTIONS and LISTS are needed to understand
> for loop. (Even recursion is "easier" with just FUNCTIONS
> to know ;-)

Making a language more complicated makes it harder to learn, not easier.
You don't need to teach 'def' before teaching the use of built-in functions.
Training wheels do not belong in a language which is used for non-learning
purposes.

Roman Suzi

unread,
May 10, 2001, 11:05:12 AM5/10/01
to Carlos Ribeiro, pytho...@python.org
On Thu, 10 May 2001, Carlos Ribeiro wrote:

>At 15:38 10/05/01 +0400, Roman Suzi wrote:
>>There is no demand for syntactically supported ranges?
>
>Yes, I think it would be a nice addition, and I'm sure we're not alone -
>many people on the group contributed with ideas on this topic. While I
>understand that there are some issues with the proposal - including or
>excluding the upper limit, using braces to delimit the range, or how to
>specify the step operator - I believe that the concerns are mostly in the
>reaction-to-change field.
>

>So, if we can propose a new syntax that:
>
>- is clear for both novices and experienced Python programmers

Then it must be asymmetrical, like "->" to remind that
right end is exclusive.

>- does not break anyone's code

Its up to the syntax. I hope, solution from [;.:=!@#$%^&|\-_~]{2}
will be found, not some word.

>- is consistent with related features (slicing and list comprehensions)

Yes, this will be automatically if it will be incl-excl range
and will not interfer with [, :, ]

>... there will be no real reason not to make it.
>

>let's talk about facts, not emotions, ok?

Sincerely yours, Roman Suzi


--
_/ Russia _/ Karelia _/ Petrozavodsk _/ r...@onego.ru _/

_/ Thursday, May 10, 2001 _/ Powered by Linux RedHat 6.2 _/
_/ "COFFEE.EXE Missing - Insert Cup and Press Any Key" _/


Douglas Alan

unread,
May 10, 2001, 12:28:04 PM5/10/01
to
"Alex Martelli" <ale...@yahoo.com> writes:

> "Douglas Alan" <nes...@mit.edu> wrote: in message

>> (Besides, I never lobbied for Python to include macros. I only stated


>> that it would be a better language if it had them. But sometimes
>> better is worse.)

> Didn't you write "Python should have procedural macros like Lisp."
> (on 2001-04-16 14:20:05 PST

Yes, and Joe's Diner should have higher ceilings and my brother should
be shorter.

I shouldn't think that expressing how something should be should
necessarily be interpreted as recommending that something that already
exists should be changed. On the other hand, you should probably
infer correctly what I would say about what should be included in
Python 3k.

|>oug

Ben Hutchings

unread,
May 10, 2001, 3:27:50 PM5/10/01
to
Douglas Alan <nes...@mit.edu> writes:

> Ben Hutchings <ben.hu...@roundpoint.com> writes:
>
> > Douglas Alan <nes...@mit.edu> writes:
>
> > > Speaking of creeping-featurism, how come we have list comprehension,
> > > but not tuple comprehension? Seems inconsistent to me.
>
> > A list contains a variable number of homogeneous values, e.g. the
> > lines of a file. Lists are like arrays in other languages. A tuple
> > contains a fixed number of heterogeneous values where each element
> > has a distinct meaning e.g. (year, month, day) for a date.
>
> I think you have some other language in mind, rather than Python. In
> Python, the only semantic difference between a list and a tuple is
> that a tuple is immutable.

Lists also have count() and index() methods, which tuples do not.
Doesn't this suggest a difference in intended purpose to you?

> > Tuples are like data structures or product types in other languages,
> > except that their types and fields are nameless. Comprehensions
> > work with a variable number of homogeneous values, so they produce
> > lists.
>
> filter() on a tuple returns a tuple. The length of the tuple cannot
> be known in advance.

<snip>

Presumably filter() only requires its argument to be a sequence.

Ben Hutchings

unread,
May 10, 2001, 3:31:15 PM5/10/01
to
Joshua Marshall <jmar...@mathworks.com> writes:

I did not, of course, mean that the values must have the same concrete
type. What I meant was that lists are normally used in a way that
allows each position in a given list to hold a value from the same set
of types/classes; there are no special rules for particular positions
in the list.

Andrew Maizels

unread,
May 10, 2001, 5:52:57 PM5/10/01
to
Alex Martelli wrote:

> I disagree. Inclusive-lower-bound, exclusive-upper-bound
> is a VERY important and useful idiom, which we should
> strive to make as widespread as we possibly can: by the
> very fact of being invariably used everywhere lower and
> upper bounds are specified, it helps a LOT against
> off-by-one errors! I first saw it explained in Koenig's
> excellent "C traps and pitfalls" book, by the way.

I can see where consistency is important, but why does Python do the
inclusive-lower-bound, exclusive-upper-bound thing?

From my point of view, there's one correct behaviour for range(1,5), and
it's NOT [1, 2, 3, 4]!

Andrew.
--
There's only one game in town.
You can't win.
You can't break even.
You can't quit the game. -- The four laws of thermodynamics.

Douglas Alan

unread,
May 10, 2001, 6:17:36 PM5/10/01
to
Ben Hutchings <ben.hu...@roundpoint.com> writes:

> Lists also have count() and index() methods, which tuples do not.
> Doesn't this suggest a difference in intended purpose to you?

I also see that tuples support "in" and "+" and "*" and slicing and
len() and min() and max(). In light of this, it seems that the fact
that they are missing count() and index() should only been seen as an
unfortunate oversight.

>>> Tuples are like data structures or product types in other
>>> languages, except that their types and fields are nameless.
>>> Comprehensions work with a variable number of homogeneous values,
>>> so they produce lists.

> > filter() on a tuple returns a tuple. The length of the tuple cannot
> > be known in advance.

> Presumably filter() only requires its argument to be a sequence.

Yes, if its sequence argument is a tuple, then it returns a tuple. If
you were right, you should never want to run filter on a tuple, and if
you were so foolish to use filter() on a tuple, it should return a
list to show you the errors of your ways. Or actually, tuples
shouldn't be sequences at all, since you should never treat a tuple as
a sequence, rather than just as a record.

|>oug

Ben Hutchings

unread,
May 10, 2001, 7:11:52 PM5/10/01
to
Douglas Alan <nes...@mit.edu> writes:

> Ben Hutchings <ben.hu...@roundpoint.com> writes:
>
> > Lists also have count() and index() methods, which tuples do not.
> > Doesn't this suggest a difference in intended purpose to you?
>
> I also see that tuples support "in" and "+" and "*" and slicing and
> len() and min() and max().

OK, you're right.

> In light of this, it seems that the fact that they are missing
> count() and index() should only been seen as an unfortunate
> oversight.

Based on the above - yes.

I'd be happier if tuples only supported len() though - because
this large overlap in tuple and list capabilities means that it's
less obvious which is a good choice for some particular purpose.

> >>> Tuples are like data structures or product types in other
> >>> languages, except that their types and fields are nameless.
> >>> Comprehensions work with a variable number of homogeneous values,
> >>> so they produce lists.
>
> > > filter() on a tuple returns a tuple. The length of the tuple cannot
> > > be known in advance.
>
> > Presumably filter() only requires its argument to be a sequence.
>
> Yes, if its sequence argument is a tuple, then it returns a tuple. If
> you were right, you should never want to run filter on a tuple, and if
> you were so foolish to use filter() on a tuple, it should return a
> list to show you the errors of your ways.

Well I think it should do that. Oh well.

> Or actually, tuples shouldn't be sequences at all, since you should
> never treat a tuple as a sequence, rather than just as a record.

It's necessary to treat tuples generically sometimes, so they need to
be sequences.

Tim Peters

unread,
May 10, 2001, 9:23:47 PM5/10/01
to pytho...@python.org
[Ben Hutchings]

>> Lists also have count() and index() methods, which tuples do not.
>> Doesn't this suggest a difference in intended purpose to you?

[Douglas Alan]


> I also see that tuples support "in" and "+" and "*" and slicing and
> len() and min() and max().

As explained in the docs, all sequence types are supposed to support those
specific operations (along w/ a few others).

> In light of this, it seems that the fact that they are missing
> count() and index() should only been seen as an unfortunate oversight.

But those aren't part of the sequence protocol (or "interface", if you like)
defined by the docs. Sequence types may or may not choose to implement them.
Tuples choose not to, and Guido has firmly rejected at least one working
patch that sought to add those methods to tuples. Ben is channeling Guido's
intent accurately here!

>>> filter() on a tuple returns a tuple. The length of the tuple cannot
>>> be known in advance.

>> Presumably filter() only requires its argument to be a sequence.

> Yes, if its sequence argument is a tuple, then it returns a tuple.

Unfortunate but true. Strings are special-cased by filter() too. Nothing
else is -- and a maze of inconsistent special cases is un-Pythonic on the
face of it.

> If you were right, you should never want to run filter on a tuple,

Indeed, I never have <0.1 wink>.

> and if you were so foolish to use filter() on a tuple, it should
> return a list to show you the errors of your ways.

That would be better. The filter() implementation was contributed code, and
snuck in along with map(), reduce() and lambda. If Guido had it to do over
again, I doubt he'd accept that patch; they're his answer to the question
"what do you like least about Python?".

> Or actually, tuples shouldn't be sequences at all, since you should
> never treat a tuple as a sequence, rather than just as a record.

As above, the Language Reference manual's idea of what "a sequence" is
doesn't match yours; so while you're entitled to say tuples shouldn't be
considered to be Douglas-sequences, claiming they're Python-sequences isn't
really open to debate.

hmm-now-i'm-wondering-what-this-msg-was-about<wink>-ly y'rs - tim


Douglas Alan

unread,
May 10, 2001, 11:21:58 PM5/10/01
to
"Tim Peters" <tim...@home.com> writes:

> As explained in the docs, all sequence types are supposed to support those
> specific operations (along w/ a few others).

Well, then, if tuples are sequences, then one shouldn't say that it is
inappropriate to treat them as sequences. If it is inappropriate to
perform sequences operations on them, then they shouldn't be
sequences. If a tuple isa sequence, then all sequence operations
should be considered appropriate.

Personally, I consider a tuple to be a full-fledged sequence. It's an
immutable sequence, while a list is a mutable sequence. Mutability is
the important distinction between a list and a tuple.

> > In light of this, it seems that the fact that they are missing
> > count() and index() should only been seen as an unfortunate
> > oversight.

> But those aren't part of the sequence protocol (or "interface", if
> you like) defined by the docs. Sequence types may or may not choose
> to implement them. Tuples choose not to, and Guido has firmly
> rejected at least one working patch that sought to add those methods
> to tuples. Ben is channeling Guido's intent accurately here!

And what's that intent? Ben claimed that tuples should only be used
when you know how many elements there will be, and that lists should
only be used for homogeneous data of unknown length. The more
straight forward conclusion would be that tuples should be used when
you want an immutable sequence and that lists should be used when you
want a mutable sequence.

> > Or actually, tuples shouldn't be sequences at all, since you should
> > never treat a tuple as a sequence, rather than just as a record.

> As above, the Language Reference manual's idea of what "a sequence"
> is doesn't match yours; so while you're entitled to say tuples
> shouldn't be considered to be Douglas-sequences, claiming they're
> Python-sequences isn't really open to debate.

You misunderstand. I think that that a tuple *should* be considered
sequence. A full-fledged one. Not one restricted to data of length
known in advance. Not restricted to heterogeneous data. A tuple
should be considered a full-fledged immutable sequence of arbitrary
Python objects. No more, no less.

|>oug

Aahz Maruch

unread,
May 10, 2001, 11:45:08 PM5/10/01
to
In article <3AFB0DB9...@one.net.au>,

Andrew Maizels <and...@one.net.au> wrote:
>
>I can see where consistency is important, but why does Python do the
>inclusive-lower-bound, exclusive-upper-bound thing?

Because it makes loops more likely to work. E.g.:


l = [1,4,9,16]
for i in range(len(l)):
print l[i]
--
--- Aahz <*> (Copyright 2001 by aa...@pobox.com)

Androgynous poly kinky vanilla queer het Pythonista http://www.rahul.net/aahz/
Hugs and backrubs -- I break Rule 6

"Everyone is entitled to an *informed* opinion." --Harlan Ellison

Rainer Deyke

unread,
May 11, 2001, 12:26:25 AM5/11/01
to
"Douglas Alan" <nes...@mit.edu> wrote in message
news:lcd79gy...@gaffa.mit.edu...

> And what's that intent? Ben claimed that tuples should only be used
> when you know how many elements there will be, and that lists should
> only be used for homogeneous data of unknown length.

And what a ridiculous claim that was. Consider:

def f(*args):
pass

'args' is a tuple. A tuple is used precisely because you *don't* know in
advance how many elements there are. Otherwise you would list the elements
individually. The contents of 'args' are almost certainly homogeneous.

And what about the case where you want to use a homogeneous sequence, length
unknown, of arbitrary Python objects as a dictionary key>

Greg Ewing

unread,
May 11, 2001, 1:32:24 AM5/11/01
to
Roman Suzi wrote:
>
> I taught programming classes a year ago.
> That is where I had some trouble with for-loops.

Maybe that's because you were trying to teach
Python for-loops as though they were Pascal for-loops,
which are designed to generate a sequence of
integers.

That's not what Python for-loops are designed for.
The purpose of a Python for-loop is to do something
for each element of a sequence, and I believe that's
how they should be presented.

It follows from this that there's no reason to
introduce for-loops until you've introduced some
kind of sequence, e.g. a list of strings.

If you want to introduce a looping structure for
some other purpose before then, don't use a for
loop, use a while loop.

Roman Suzi

unread,
May 10, 2001, 3:07:54 PM5/10/01
to pytho...@python.org
On Thu, 10 May 2001, Rainer Deyke wrote:

>"Carlos Ribeiro" <crib...@mail.inet.com.br> wrote in message
>news:mailman.989496615...@python.org...
>> So, if we can propose a new syntax that:
>>
>> - is clear for both novices and experienced Python programmers
>> - does not break anyone's code
>> - is consistent with related features (slicing and list comprehensions)
>>
>> ... there will be no real reason not to make it.
>
>Only if you don't value simplicity. If this is the case, why are you using
>Python at all?

I do not see how syntactical ranges could spoil simplicity!

Christian Tanzer

unread,
May 11, 2001, 2:28:43 AM5/11/01
to pytho...@python.org

Roman Suzi <r...@onego.ru> wrote :

> I do not see how syntactical ranges could spoil simplicity!

That's exactly the problem <wink>.

--
Christian Tanzer tan...@swing.co.at
Glasauergasse 32 Tel: +43 1 876 62 36
A-1130 Vienna, Austria Fax: +43 1 877 66 92


Fredrik Lundh

unread,
May 11, 2001, 3:28:09 AM5/11/01
to
Douglas Alan wrote:
>
> I also see that tuples support "in" and "+" and "*" and slicing and
> len() and min() and max(). In light of this, it seems that the fact
> that they are missing count() and index() should only been seen as an
> unfortunate oversight.

more likely, it's because you don't know your python well enough.

the core sequence interface (PySequenceMethods) includes the
following methods:

__len__
__add__ (concat)
__mul__ (repeat)
__getitem__, __setitem__, __delitem__
__getslice__, __setslice__, __delslice__

like most other operations that work on sequences, min() and max()
only require you to have working __len__ and __getitem__ methods.

none of the methods provided by list objects are part of the core
sequence protocol.

> Yes, if its sequence argument is a tuple, then it returns a tuple

which probably is an unfortunate oversight, since it returns lists
for all other sequences:

>>> from UserList import UserList
>>> L = UserList((1, 2, 3, 4))
>>> filter(None, L)
[1, 2, 3, 4]
>>> type(filter(None, L))
<type 'list'>

> If you were right, you should never want to run filter on a tuple, and if
> you were so foolish to use filter() on a tuple, it should return a
> list to show you the errors of your ways. Or actually, tuples
> shouldn't be sequences at all, since you should never treat a tuple as
> a sequence, rather than just as a record.

since ben is right, I'm glad you're not in charge of python's design.

Cheers /F


Fredrik Lundh

unread,
May 11, 2001, 3:28:09 AM5/11/01