Search code examples
iteratorlualanguage-design

Why are Lua's iterators triples?


Lua 5.1's reference manual states that an iterator

 for var_1, ···, var_n in explist do block end

is equivalent to the code:

 do
   local f, s, var = explist
   while true do
     local var_1, ···, var_n = f(s, var)
     var = var_1
     if var == nil then break end
     block
   end
 end

Why does Lua require the 'state' variable, s?

I would guess that it means that the iterator function does not need to carry any per-iterator state (see, e.g., the design of the ipairs iterator-yielding function), however it is quite straightforward to create closures on demand that carry this state, and the cost is pretty much once per iteration, the efficiency-based case is not that clear to me.


Solution

  • Because the triple design doesn't prevent you from using a closure, while the alternative approach prevents you from not using closures. Sometimes the external-state design is the simpler approach.

    For instance, say that you're using a for loop to iterate which pages to display in the response to a RESTful query. With external-state-based loops, you can write a function that iterates pages based on a table representing the state-representational parameters of the query (which you construct from the URL once and reuse for several other functions). With triples, you can iterate with just those values without being forced to wrap it (and every other function like it) in a closure constructor.