Functions
Learn Lua function syntax, first-class functions, multiple return values, variadic arguments, and the colon method-call sugar.
Introduction
Functions in Lua are ordinary values — they can be stored in variables and tables, passed as arguments, and returned from other functions, exactly like a number or a string. This lesson covers function syntax and three features (multiple returns, variadic arguments, and colon-call sugar) that show up constantly in idiomatic Lua code.
- How to declare named and anonymous functions.
- Why functions being first-class values matters in practice.
- How a single function can return more than one value.
- How variadic arguments (...) and the colon method-call sugar work.
Declaring Functions
local function greet(name) return "Hello, " .. name .. "!"end
print(greet("Meera"))
-- an anonymous function, assigned to a variablelocal square = function(x) return x * xend
print(square(5))Click Run to see what this code prints.
local function name(...) is exactly equivalent to local name = function(...) — it's simply clearer syntax for the common case of naming a function up front.
Functions Are First-Class Values
Because functions are ordinary values, you can store them in a table (as seen in lesson 6's table-dispatch pattern), pass them as arguments to other functions, and return them from other functions — the basis for callbacks, event handlers, and much of Lua's flexibility.
local function applyTwice(fn, value) return fn(fn(value))end
local function addOne(x) return x + 1end
print(applyTwice(addOne, 5)) -- addOne(addOne(5)) = 7Click Run to see what this code prints.
Multiple Return Values
A Lua function can return more than one value in a single return statement — genuinely useful, and different from languages that require packing multiple values into a tuple or object first.
local function minMax(numbers) local lo, hi = numbers[1], numbers[1] for _, n in ipairs(numbers) do if n < lo then lo = n end if n > hi then hi = n end end return lo, hiend
local smallest, largest = minMax({4, 8, 1, 9, 3})print(smallest, largest)Click Run to see what this code prints.
Variadic Arguments
A function parameter list ending in ... accepts any number of extra arguments, accessible as a special expression you can capture into a table or pass along directly.
local function sum(...) local total = 0 for _, n in ipairs({...}) do total = total + n end return totalend
print(sum(1, 2, 3, 4, 5))Click Run to see what this code prints.
The Colon (:) Method Sugar
When you define or call a function using : instead of ., Lua automatically adds (or passes) the table itself as the first argument, conventionally named self — the exact mechanism referenced back in lesson 1's example, and the foundation of Lua's object-oriented patterns in lesson 9.
local counter = {value = 0}
function counter:increment() -- sugar for: function counter.increment(self) self.value = self.value + 1end
counter:increment() -- sugar for: counter.increment(counter)counter:increment()print(counter.value)Click Run to see what this code prints.
Common Mistakes
- Mixing up . and : when defining or calling a method — a . definition needs an explicit self parameter; a : definition adds it automatically.
- Assuming extra returned values are silently dropped in every context — they usually are when not all are captured, but table constructors and function calls in the middle of an argument list only keep the first value.
- Forgetting that {...} is required to safely collect variadic arguments into a table for iteration.
Best Practices
- Prefer local function name(...) over an anonymous function assignment when the function has an obvious, reusable name.
- Use multiple return values for small, related pieces of data (like min/max) instead of manually constructing a table just to return two things.
- Use the colon syntax consistently once a table starts behaving like an object with methods (lesson 9 builds on this directly).
Frequently Asked Questions
Not built into the syntax directly — the idiomatic pattern is param = param or defaultValue at the top of the function body, relying on Lua's truthy/falsy rules from lesson 4.
It's simply a conventional parameter name for "the table this method was called on" — nothing special about the word itself, just a strong convention every Lua codebase follows.
Not yet — closures (functions that capture variables from their enclosing scope) get a full dedicated lesson next, since they deserve real depth.
Key Takeaways
- Functions are first-class values in Lua — they can be stored, passed, and returned like any other value.
- A single function can return multiple values in one return statement.
- A ... parameter accepts variadic arguments, safely collected into a table with {...}.
- The colon (:) syntax automatically passes the table as self, the foundation of Lua's object-oriented patterns.
Summary
Functions being first-class, multi-return values with a self-passing shortcut is a big part of what makes Lua feel expressive despite its small size. Next, you'll cover closures — how a function can remember and modify variables from the scope it was created in.