Varargs, as they are commonly known, allow functions to take an arbitrary number of arguments without specification. All arguments given to such a function are packaged into a single structure known as the vararg list; which is written as ...
in Lua. There are basic methods for extracting the number of given arguments and the value of those arguments using the select()
function, but more advanced usage patterns can leverage the structure to it's full utility.
Efficiency
The vararg list is implemented as a linked list in the PUC-Rio implementation of the language, this means that indexes are O(n). That means that iterating over the elements in a vararg using select()
, like the example below, is an O(n^2) operation.
for i = 1, select('#', ...) do
print(select(i, ...))
end
If you plan on iterating over the elements in a vararg list, first pack the list into a table. Table accesses are O(1), so iterating is O(n) in total. Or, if you are so inclined, see the foldr()
example from the advanced usage section; it uses recursion to iterate over a vararg list in O(n).
Sequence Length Definition
The vararg is useful in that the length of the vararg respects any explicitly passed (or computed) nils. For example.
function test(...)
return select('#', ...)
end
test() --> 0
test(nil, 1, nil) --> 3
This behavior conflicts with the behavior of tables however, where the length operator #
does not work with 'holes' (embedded nils) in sequences. Computing the length of a table with holes is undefined and cannot be relied on. So, depending upon the values in ...
, taking the length of {...}
may not result in the 'correct' answer. In Lua 5.2+ table.pack()
was introduced to handle this deficiency (there is a function in the example that implements this function in pure Lua).
Idiomatic Use
Because varargs carry around their length people use them as sequences to avoid the issue with holes in tables. This was not their intended usage and one the reference implementation of Lua does not optimize for. Although such usage is explored in the examples, it is generally frowned upon.