Variadic Functions and table.pack/unpack
Lua functions can accept a variable number of arguments using ... (the vararg expression), and tables can be converted to and from argument lists with table.pack/table.unpack.
Accepting any number of arguments
{...} packs all the varargs into a plain table, from there ipairs works as usual. This breaks down if any argument is nil, though, since ipairs stops at the first nil.
select: inspecting varargs directly
select("#", ...) returns the exact argument count, including trailing nils, unlike #{...} which can undercount if a nil is in the middle or at the end. select(n, ...) returns every argument from position n onward.
table.pack and table.unpack
table.pack(...) is exactly {...} plus a reliable n field for the true count (nil-safe, unlike #). table.unpack(t) does the reverse, spreading a table's elements out as individual values, handy for forwarding a captured argument list to another function: someFn(table.unpack(args)).
TIP
A common pattern is combining both: capture arguments now with table.pack, and call a function with them later using table.unpack, effectively deferring a function call, exactly what you'd reach for spread syntax for in JavaScript.