🎓 A1Learner
🔍
0 of 52 lessons completed

Lua Stateless Iterators

A stateless iterator is a plain function that keeps no position of its own and receives its position from the for loop on each call. The for loop supplies a state value and a control value, and the iterator returns the next control value and the next item.

The iterator takes state and control and returns the next pair

The state is the fruit table. The control value is the last index used.

local function next_item(t, i)
  i = i + 1
  if i <= #t then
    return i, t[i]
  end
  return nil
end
local fruits = {"apple", "banana", "cherry"}
print(next_item(fruits, 0))
print(next_item(fruits, 1))
print(next_item(fruits, 3))

The for loop supplies state and control

The for loop starts with control value 0. Each step feeds the returned index back as the next control value.

local function next_item(t, i)
  i = i + 1
  if i <= #t then
    return i, t[i]
  end
  return nil
end
local fruits = {"apple", "banana", "cherry"}
for i, fruit in next_item, fruits, 0 do
  print(fruit)
end

Control values keep two walks separate

The function stores no position. Different control values start the walk at different places.

local function next_item(t, i)
  i = i + 1
  if i <= #t then
    return i, t[i]
  end
  return nil
end
local fruits = {"apple", "banana", "cherry"}
print(next_item(fruits, 0))
print(next_item(fruits, 2))
print(next_item(fruits, 1))

Example

local function next_step(state, current)
  local value = current + state.step
  if value <= state.limit then
    return value
  end
  return nil
end
local state = {limit = 12, step = 3}
for v in next_step, state, 0 do
  print(v)
end
print(next_step(state, 0))

Key points

  • State value: a value the for loop passes to the iterator unchanged on every call.
  • Control value: the value that tells the iterator where the last call stopped.
  • Iterator function: a plain function that takes a state value and a control value and returns the next control value and the next item.
  • For loop protocol: the for loop calls the function with the state value and the control value and stops when the first returned value is nil.
  • No stored position: two uses of the same iterator function can run at the same time without sharing a position.

In this example, the iterator adds the step from the state table to the current control value. The for loop starts at 0 and prints 3, 6, 9, and 12. The final manual call starts again from 0 and returns 3, which shows the function kept no position of its own.

Note

ipairs is a built-in stateless iterator whose state is the table and whose control value is the index.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

In the loop for v in next_step, state, 0 do, what does the for loop pass to next_step on its second call?