LUA / CHAPTER 10

Custom iterators and termination contracts

Advanced

Expose a traversal without exposing its storage representation.

By the end of this chapter

  • Return successive values from an iterator closure
  • Use nil as the termination signal
  • Keep traversal state independent per iterator

The idea

A generic for loop repeatedly calls an iterator and stops when its first returned value is nil. A closure iterator can keep its position private while exposing one value at a time. This allows callers to traverse a computed sequence without knowing whether the implementation stores a table, calculates values, or reads from another source.

Choose a yielded shape whose first value cannot be confused with termination. If nil is valid data, yield a non-nil index first and put the data in a later result. Create a fresh iterator for independent traversals instead of reusing one exhausted stateful closure. Document when traversal completes and whether it owns resources that need cleanup after early termination.

Lua example
local function stepper(limit)
  local n=0
  return function()
    n=n+1
    if n<=limit then return n*2 end
  end
end
for value in stepper(3) do print(value) end
Result
2
4
6

Each call advances private state. Once the limit is exceeded, the iterator returns nil and the generic loop ends.

Try it yourself

Design an indexed iterator that can yield nil data values without ending early.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Which iterator result tells a generic for loop to stop?