Re: unevaluated sequences of initially indefinite length and 'filter'

Tim Peters (tim@ksr.com)
Thu, 24 Feb 94 23:57:12 EST

> [guido]
> ...
> (2) A possibly even more efficient way of doing this, which might work
> for 'for' loops as well, would be to never ask for the length at all
> -- simply keep asking for the next element until it raises IndexError.
> ... [cogent agreement from steve] ...
> And we would have introduced generators in the language without any
> major surgery!

Cool! And if the user chooses never to raise IndexError, they've got a
keen way to model infinite lazy lists, too. Question: I assume the
following wouldn't work as is, but do you have in mind a way to make it
work (special method name, whatever)?

class GenInts:
def __init__(self, n):
self.n = n

def next(self):
n = self.n
try:
self.n = n + 1
except OverflowError:
self.n = long(n) + 1
return n

from2 = GenInts(2)
for prime in filter( no_proper_divisors, from2.next() ):
print 'they never seem to end!', prime

And if you can make that work, what would happen if I made similar
changes in this:

i = GenInts(1)
j = GenInts(1)
for mystery_tuple in map( lambda x,y: (x,y), i.next(), j.next() ):
print mystery_tuple

I.e., once there's a generator-like object, there are subtle design
questions about how and when its generator-like behavior is triggered.

One nit: I think overloading IndexError to mean "no more in the
sequence" is as aesthetically repugnant as Steve's gonzo (but effective!)
hack of making a liar out of "len". You haven't over-indexed the
sequence, you've flowed over its end -- so OverflowError is the clear
choice.

seriously-it-should-be-a-new-exception-and-not-called-"...Error"-at-all-
ly y'rs - tim

Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp