# Lua Iterators Stateless Iterators

## Example

Both pairs and ipairs represent stateless iterators. A stateless iterator uses only the generic for loop's control variable and invariant state to compute the iteration value.

## Pairs Iterator

We can implement the stateless pairs iterator using the next function.

-- generator function which initializes the generic for loop
local function pairs(t)
-- next is the iterator function
-- t is the invariant state
-- control variable is nil
return next, t, nil
end

## Ipairs Iterator

We can implement the stateless ipairs iterator in two separate functions.

-- function which performs the actual iteration
local function ipairs_iter(t, i)
local i = i + 1  -- next index in the sequence (i is the control variable)
local v = t[i]   -- next value (t is the invariant state)
if v ~= nil then
return i, v    -- index, value
end
return nil       -- no more values (termination)
end

-- generator function which initializes the generic for loop
local function ipairs(t)
-- ipairs_iter is the iterator function
-- t is the invariant state (table to be iterated)
-- 0 is the control variable (first index)
return ipairs_iter, t, 0
end

## Character Iterator

We can create new stateless iterators by fulfilling the contract of the generic for loop.

-- function which performs the actual iteration
local function chars_iter(s, i)
if i < #s then
i = i + 1
return i, s:sub(i, i)
end
end

-- generator function which initializes the generic for loop
local function chars(s)
return chars_iter, s, 0
end

-- used like pairs and ipairs
for i, c in chars 'abcde' do
print(i, c) --> 1 a, 2 b, 3 c, 4 f, 5 e
end

## Prime Numbers Iterator

This is one more simple example of a stateless iterator.

-- prime numbers iterator
local incr = {4, 1, 2, 0, 2}
function primes(s, p, d)
s, p, d = s or math.huge, p and p + incr[p % 6] or 2, 1
while p <= s do
repeat
d = d + incr[d % 6]
if d*d > p then return p end
until p % d == 0
p, d = p + incr[p % 6], 1
end
end

-- print all prime numbers <= 100
for p in primes, 100 do  -- passing in the iterator (do not call the iterator here)
print(p)  -->  2  3  5  7  11 ... 97
end

-- print all primes in endless loop
for p in primes do  -- please note: "in primes", not "in primes()"
print(p)
end