LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 719 min read

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.

What You Will Learn
  • 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 variable
local square = function(x)
return x * x
end
print(square(5))
Output

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 + 1
end
print(applyTwice(addOne, 5)) -- addOne(addOne(5)) = 7
Output

Click 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, hi
end
local smallest, largest = minMax({4, 8, 1, 9, 3})
print(smallest, largest)
Output

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 total
end
print(sum(1, 2, 3, 4, 5))
Output

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 + 1
end
counter:increment() -- sugar for: counter.increment(counter)
counter:increment()
print(counter.value)
Output

Click Run to see what this code prints.

Common Mistakes

Avoid These 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.

Next Lesson →

Closures & Scope