The in
keyword is only used joined with a for
loop in Lua/Luau. The values (e.g. i, v
) are simply the values that the iterator function returns (cf. @AskWisp’s response). Technically an iterator can return any number of arguments.
The arguments after in
are the iterator function and its initial arguments that are passed to the iterator on the first iteration. When you use an iterator generator like pairs()
or ipairs()
, these return a new function (the iterator) along with the initial arguments. E.g. if you do print(pairs({}))
, you will print the iterator function, the table itself, and the starting index (nil
).
Typically, you shouldn’t need to worry about any of this stuff. Creating custom iterators can be of some use, but very limited in my experience. In over 15 years, I’ve maybe had to write 5 or so custom iterator functions in Lua.
This hopefully explains why doing for k, v in pairs(t) do
is equivalent to for k, v in next, t do
. Because, pairs
is returning next
, along with nil
(the starting index, which next
interprets as “go to the first item”). Thus, pairs(t)
could expand to next, t
in terms of a generic for
loop.
So the human-readable signature could look something like this:
for key, value in iteratorFunction, ...initialArgsToTheIterator do
Every time the iteratorFunction
is called (each iteration of the loop), it is responsible for going to whatever the next value is expected and returning said value (e.g. key, value
). If the iterator returns nil
, the iteration is considered complete and the for
loop exists.