Varargs and the ... Operator
Handle variable-length argument lists using ... and select().
Varargs and the ... Operator is a free Lua Academy lesson on CoddyKit. This is lesson 3 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, and your progress syncs across the web and the CoddyKit app. The Lua Academy course includes 4 lessons in total.
Variable Arguments
A Lua function can accept a variable number of arguments using ... (three dots) in the parameter list. Inside the function, ... represents the extra arguments. You can use it in expressions, pass it to other functions, or convert it to a table.
local function sum(...)
local total = 0
for _, v in ipairs({...}) do
total = total + v
end
return total
end
print(sum(1, 2, 3)) -- 6
print(sum(10, 20, 30, 40)) -- 100select() for Varargs
select(n, ...) returns arguments from position n onward. select("#", ...) returns the total count of arguments including nil values. This is safer than #{...} which stops at the first nil hole.
local function inspect(...)
local n = select("#", ...)
print("count:", n)
for i = 1, n do
print(i, select(i, ...))
end
end
inspect("a", "b", nil, "d")
-- count: 4
-- 1 a
-- 2 b
-- 3 nil
-- 4 dPassing ... to Another Function
You can forward varargs directly to another function with f(...). When ... appears as the last argument in a call, all the variable arguments are passed. This is useful for wrapping functions or logging.
local function log(level, ...)
io.write("[" .. level .. "] ")
print(...)
end
log("INFO", "Server started on port", 8080)
log("ERROR", "File not found:", "config.lua")
-- [INFO] Server started on port 8080
-- [ERROR] File not found: config.luatable.pack and table.unpack
Convert varargs to a table with table.pack(...), which also stores the count in field n. Convert a table back to varargs with table.unpack(t, i, j). Together, these functions give you full control over variable argument lists.
local function pack_and_show(...)
local packed = table.pack(...)
print("n =", packed.n)
for i = 1, packed.n do
print(i, packed[i])
end
end
pack_and_show(10, nil, 30)
-- n = 3
-- 1 10
-- 2 nil
-- 3 30Mixed Fixed and Variable Args
A function can have both fixed and variable parameters. Fixed parameters come first; ... captures the rest. The fixed parameters are assigned before the rest go into ....
local function printf(fmt, ...)
io.write(string.format(fmt, ...))
end
printf("Hello, %s! You are %d years old.\n", "Alice", 30)
printf("Pi is approximately %.4f\n", math.pi)
local function firstAndRest(first, ...)
print("first:", first)
print("rest count:", select("#", ...))
end
firstAndRest(1, 2, 3, 4)Varargs in Table Constructor
You can splat varargs directly into a table constructor: {...}. When used as the last element, all args are included. However, nil holes may confuse # — prefer table.pack when you need exact counts.
local function toArray(...)
return {...} -- collect all args as array
end
local arr = toArray("x", "y", "z")
for i, v in ipairs(arr) do
print(i, v)
end
-- 1 x
-- 2 y
-- 3 zVararg Expressions
... can appear in any expression position. In a multiple assignment, it expands to all its values. In an arithmetic expression, only the first value is used. Understanding this behavior prevents subtle bugs when mixing ... with other expressions.
local function first(...)
local x = ...
return x
end
print(first(10, 20, 30)) -- 10 (only first)
local function addFirst(n, ...)
local x = ...
return n + x
end
print(addFirst(5, 3, 99)) -- 8 (3 is first ...)print() Uses Varargs
Lua's built-in print() is itself a vararg function. It accepts any number of arguments, converts each to a string, and separates them with tabs. Understanding this helps you write similar utility functions.
-- print is vararg
print(1, 2, 3) -- 1 2 3
print("a", nil, "b") -- a nil b
print() -- (empty line)
-- Reimplementing a simple print-like function
local function myprint(...)
local parts = {}
for i = 1, select("#", ...) do
parts[i] = tostring(select(i, ...))
end
io.write(table.concat(parts, "\t") .. "\n")
end
myprint(10, nil, 30)Forwarding with pcall
Combine pcall with varargs to create a generic safe-call wrapper. The wrapper accepts a function and any arguments, calls it via pcall, and returns the results or an error.
local function safeCall(fn, ...)
local ok, result = pcall(fn, ...)
if ok then
return result
else
print("Error:", result)
return nil
end
end
local function divide(a, b)
assert(b ~= 0, "division by zero")
return a / b
end
print(safeCall(divide, 10, 2)) -- 5.0
print(safeCall(divide, 10, 0)) -- Error: ...Accumulate Varargs Pattern
A common vararg pattern is to iterate over all arguments and accumulate a result. This can be done with a local table or by directly summing with select. Both approaches are valid; the table approach is cleaner for many arguments.
local function average(...)
local n = select("#", ...)
if n == 0 then return 0 end
local total = 0
for i = 1, n do
total = total + select(i, ...)
end
return total / n
end
print(average(10, 20, 30, 40)) -- 25.0
print(average(5)) -- 5.0Quick Check
What does select("#", 1, nil, 3) return?
Recap: Varargs
Summary:
function f(...)— accepts variable argumentsselect("#", ...)— safe count including nilsselect(n, ...)— values from position ntable.pack(...)— varargs to table with .n counttable.unpack(t)— table to varargs...in last position expands fully; middle position gives one value
Learn Lua with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 40
- Lessons
- 159
Frequently Asked Questions
Is the “Varargs and the ... Operator” lesson free?
Yes — any 3 lessons of the Lua Academy learning path, including “Varargs and the ... Operator”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Lua Academy course includes 4 lessons in total.
What will I learn in “Varargs and the ... Operator”?
Handle variable-length argument lists using ... and select(). You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Lua Academy?
No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 3 of 4.
How long does the “Varargs and the ... Operator” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Lua Academy lesson?
Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Defining and Calling Functions
- Multiple Return Values
- Varargs and the ... Operator
- Recursion in Lua