Functions & Closures
Function syntax
Named function
function add(a, b)
return a + b
end
Anonymous function (lambda)
local add = function(a, b)
return a + b
end
Method syntax (adds implicit self)
function obj:greet(name)
print(self.name .. " says hi to " .. name)
end
-- Equivalent to:
function obj.greet(self, name) ... end
-- Call with colon syntax:
obj:greet("Lua") -- passes obj as first arg
Parameters
Regular parameters
function f(a, b, c)
print(a, b, c)
end
f(1, 2, 3) -- 1 2 3
f(1, 2) -- 1 2 nil
f(1, 2, 3, 4) -- 1 2 3 (extra discarded)
Default values (idiom)
LuaLuaA lightweight, embeddable scripting language used as the primary scripting language in FiveM server development. has no built-in defaults. Use or:
function greet(name)
name = name or "World"
print("Hello, " .. name)
end
Multiple return values
function swap(a, b)
return b, a
end
local x, y = swap(1, 2) -- x=2, y=1
When multiple returns are kept/discarded
function multi() return 1, 2, 3 end
-- Kept: at end of expression list
local a, b, c = multi() -- 1, 2, 3
print(multi()) -- 1, 2, 3
return multi() -- passes all 3
-- Discarded: in middle of expression list
local a, b = multi(), 99 -- a=1, b=99 (2,3 discarded)
local a = (multi()) -- a=1 (parens force single value)
Varargs
function f(a, b, ...)
local args = {...} -- capture as table
print(select("#", ...)) -- count of varargs
print(...) -- pass through
end
f(1, 2, 3, 4, 5)
-- args = {3, 4, 5}
-- select("#", ...) = 3
select function
select(i, ...) -- returns args from i onward
select("#", ...) -- returns count of varargs
print(select(3, "a", "b", "c", "d")) -- c d
Closures
Functions can capture outer local variables (upvalues). The captured variable persists even after the outer scope ends.
function counter()
local n = 0
return function()
n = n + 1
return n
end
end
local c = counter()
print(c()) -- 1
print(c()) -- 2
print(c()) -- 3
Shared upvalues
Multiple closures can share the same upvalue:
function make_getter_setter()
local value = 0
return {
get = function() return value end,
set = function(v) value = v end,
}
end
local gs = make_getter_setter()
gs.set(42)
print(gs.get()) -- 42
First-class functions
Functions are values — store in tables, pass as args, return from functions.
-- Store in table
local ops = {
add = function(a, b) return a + b end,
sub = function(a, b) return a - b end,
}
print(ops.add(1, 2)) -- 3
-- Higher-order function
function apply(f, x, y)
return f(x, y)
end
print(apply(ops.mul or ops.add, 3, 4)) -- 7
-- Sorting with custom comparator
local t = {3, 1, 4, 1, 5}
table.sort(t, function(a, b) return a < b end)
pcall and protected calls
local ok, result = pcall(function()
error("something went wrong")
end)
print(ok) -- false
print(result) -- something went wrong
See Error-Handling for full details.
Tail calls
A tail call occurs when a function call is the last action before return. LuaLuaA lightweight, embeddable scripting language used as the primary scripting language in FiveM server development. optimizes this to avoid growing the stack.
function factorial(n, acc)
acc = acc or 1
if n <= 1 then return acc end
return factorial(n - 1, n * acc) -- tail call
end
print(factorial(100000)) -- no stack overflow
Requirements for tail call:
- Call must be the last action in the function
- No further operations after the call
- Cannot be in a
return f(), g()(that's multiple returns)
Function properties
| Property | Value |
|---|---|
| Type | "function" |
| Equality | By reference (same closure = same) |
| Comparison | Only == and ~= (no <) |
| Garbage collected | Yes (with upvalues) |