Re: Non-list ranges; iterators in general

Tim Peters (tim@ksr.com)
Wed, 27 Oct 93 19:04:45 -0400

> [guido times a range object implementation with discouraging results]
> ...
> My personal conclusion: it's not worth optimizing range() at all...

No argument here -- & very interesting.

> [discussion of iterators]

> [steve]
> ...
> [Note: Icon handles this [breaking out of an iterator loop] by having a
> special value for failure. ]

Well, it's kinda _implemented_ that way, but the user doesn't (need to)
know anything about that. _Every_ expression in Icon generates a
sequence of 0 or more results, and to say that an Icon expression "fails"
is the same as saying the expression has an empty (length 0) result
sequence.

The point is that iterators fit naturally into such a scheme, since
they're just one more expression that yields 0 or more results. It's
hard to see how to support this in a general way without buying into the
whole co-routine business, and that seems like a lot of new machinery for
Python.

People might be interested in seeing how this works in Icon. So here's
an Icon version of the Fibonacci example. Abstractly, it looks much like
Basic2's approach:

procedure main()
every x := fib() do
if x < 500 then write( x )
else break
end

procedure fib()
local a, b, sum
a := b := 1 # vanilla multiple assignment
repeat { # infinite loop
suspend a # 'suspend' sez to return the value, & also allow resuming
sum := a + b
a := b
b := sum
}
end

That prints

1
1
2
3
5
8
13
21
34
55
89
144
233
377

The successive generation of fib's values is driven by the "every"
control structure. A kind of closure can also be created by the "create"
construct, and resumed as desired with the invocation operator "@"; e.g.,

procedure main()
thunk := create fib()
write( @thunk )
write( @thunk )
write( @thunk )
write( @thunk )
end

prints

1
1
2
3

More general mechanisms exist for passing control in arbitary co-routine
fashion, etc.

This is all very slick in theory, but in my experience Icon's
implementation of these features is burdensome & buggy. Icon was
designed for exploring new language ideas, so that's fine for Icon. I
don't think it fits Python's worldview, though.

> [ Could there be a special "loop break" exception ,
> which is caught and invisibly handled in loops ? ]

That seems the cleanest way to get the most useful part of the
functionality in Python, but I worry more about how much hair it would
add to permit suspending & resuming the "sequence" part of "for thing in
sequence:".

> [steve]
> ...
> So if I could think of a good proposal to make 'for' more "object-
> oriented" ( i.e. behave differently for different objects ), I'ld tend
> to be in favor of it. But I agree that additional feature's aren't
> *necessary*, so I don't think they are worth considering unless they
> can fit in without much trouble.

Agreed on all counts.

harmoniously y'rs - tim

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