More on Iterators and Iteration

Iterators are one of my favorite language features or design pattern. They're a feature that, when done correctly, basically vanishes.

Back in the bad old days, you had Basic:

for i = 1 to 20 step 2
next i

Then you had C:

for(i=0;i<=20;i+=2) ...

Then you had object oriented languages:

while( x = foo->next() ) ...

Then the scripting languages came back with an even better version:

foreach($s as $x=>$y)

Then, they merged the two. PHP has an interesting iterator. It makes foreach act like while(....->next()).

Icon has a feature called generators:

every write(!lines)

Example from Icon presentation

Icon can even nest generators:

every sum +:= !split(!&input, ' \t')

That example is equivalent to two nested loops. The implication is that with generators, you can devise more complex iterations over your data.

Python and Javascript have generators, but the discussion about them focuses more on writing function that use yield to return a value, but the function maintains state.

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

Other, more Lisp-like features related to iterators are appy() and map(), where you apply a function to all the elements in an array. Python and Javascript have list comprehensions.

Coming at it from another direction, SQL treats all data as tables, and all operations imply looping:

update foo set i=i+1

Not only is the looping implicit, there isn't really a simple way to address a single element.

Over time, iterating has changed from manipulating indexes into arrays, to syntax that reads more like direct manipulation, to one-liners. SQL comes from a different tradition, and assumes you always want to apply your operations to a set of data.

cards.jpg8.36 KB