You are on page 1of 2

This first edition was written for Lua 5.0.

While still largely relevant for later versions, there are


some differences.
The fourth edition
targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

Programming in Lua
Part I. The Language
Chapter 7. Iterators and the Generic for

7.3 – Stateless Iterators


As the name implies,
a stateless iterator is an iterator that
does not keep any
state by itself.
Therefore, we may use the same stateless iterator in multiple
loops,
avoiding the cost of creating new closures.

On each iteration,
the for loop calls its iterator function with two arguments:
the invariant state and the control variable.
A stateless iterator generates the
next element for
the iteration using only these two arguments.
A typical
example of this kind of iterator is ipairs,
which iterates over all elements in
an array,
as illustrated next:

a = {"one", "two", "three"}

for i, v in ipairs(a) do

print(i, v)

end

The state of the iteration is the table being traversed


(the invariant state,
which does not change during the loop),
plus the current index (the control
variable).
Both ipairs and the
iterator it returns are quite simple;
we could
write them in Lua as follows:

function iter (a, i)

i = i + 1

local v = a[i]

if v then

return i, v

end

end

function ipairs (a)

return iter, a, 0

end

When Lua calls ipairs(a) in a for loop,


it gets three values:
the iter function
as the iterator,
a as the invariant state,
and zero as the initial value for the
control variable.
Then, Lua calls iter(a, 0),
which results in 1, a[1]
(unless
a[1] is already nil).
In the second iteration, it calls iter(a, 1),
which results
in 2, a[2], and so on,
until the first nil element.

The pairs function,


which iterates over all elements in a table, is similar,
except that the iterator function is the next function,
which is a primitive
function in Lua:

function pairs (t)

return next, t, nil

end

The call next(t, k), where k is a key of the table t,


returns a next key in the
table,
in an arbitrary order.
(It returns also the value associated with that key,
as a second return value.)
The call next(t, nil) returns a first pair.
When
there are no more pairs, next returns nil.

Some people prefer to use next directly,


without calling pairs:

for k, v in next, t do

...

end

Remember that the expression list of the for loop is


adjusted to three results,
so Lua gets next, t, and nil,
exactly what it gets when it calls pairs(t).

Copyright © 2003–2004 Roberto Ierusalimschy. All rights reserved.

You might also like