21. Functions
You have called functions since Chapter 7 — print,
io.read, tonumber, math.random,
string.format. Now you write your own: a function names a
chunk of work you can reuse.
Defining and calling
The simplest definition:
local function greet()
print("Hello!")
end
greet() -- prints Hello!
greet() -- prints Hello! againRead it as: define a local function greet that takes
no arguments and runs the body when called. end closes
the body; call it by writing its name with ().
local is the same keyword you use for variables: it
keeps the function private to the file. Skip it and it goes global — as
always, use local.
Parameters
A function takes inputs as parameters in parentheses:
local function greet(name)
print("Hello, " .. name .. "!")
end
greet("Keiko") -- Hello, Keiko!
greet("Roblox") -- Hello, Roblox!name lives for one call; the caller supplies its value
(the argument) by position. With more than one:
local function add(a, b)
print(a .. " + " .. b .. " = " .. (a + b))
end
add(3, 4) -- 3 + 4 = 7Missing arguments become nil; extra ones are silently
ignored.
greet() -- name is nil; tries to concatenate nil and errors
add(1, 2, 3, 4) -- works, 3 and 4 are ignoredreturn — handing a
value back
To produce a value instead of printing, use
return:
local function square(n)
return n * n
end
local result = square(5)
print(result) -- 25
print(square(7)) -- 49
print(square(3) + 1) -- 10return ends the function at once and hands the value
back. A function with no return returns
nil.
Open exercises/21/01-square.lua. Add a function
cube(n) that returns n * n * n, then call
cube(3).
Multiple return values
A Lua function can return several values at once:
local function divmod(a, b)
return a // b, a % b
end
local q, r = divmod(17, 5)
print(q, r) -- 3 2This is one of Lua's nicest features. It returns in chapter 22 with
table.unpack, and you saw it in chapter 11 as
a, b = b, a — the swap trick from the other side.
Where only one value is expected (inside a .., or as an
argument), only the first is kept; the rest are discarded.
Early return for
guard checks
Since return ends the function at once, it is handy for
the easy cases first:
local function absolute(n)
if n >= 0 then
return n
end
return -n
end
print(absolute(5)) -- 5
print(absolute(-7)) -- 7No else is needed: if the first branch matches, the
function exits there and the line after the if never runs.
This is a guard, or early return.
Scope: where variables live
A local lives inside the block where it was declared —
for a function, the body. Once it returns, those locals are gone:
local function counter_step()
local count = 0
count = count + 1
return count
end
print(counter_step()) -- 1
print(counter_step()) -- 1 (not 2)
print(counter_step()) -- 1Every call gets a fresh count. To keep a value across
calls, declare it outside the function:
local count = 0
local function step()
count = count + 1
return count
end
print(step()) -- 1
print(step()) -- 2
print(step()) -- 3It works because the inner function can see and change the
count above it. You will use this pattern often.
Homework
Problem 1 — Greet
Open exercises/21/homework/01-greet.lua. Write a
local function greet(name) that prints
Hello, <name>!. Call it with three different
names.
Problem 2 — is_even
Open exercises/21/homework/02-is-even.lua. Write
is_even(n) that returns (not prints)
true or false for whether n is
even. Call it on a few values inside print so the booleans
show.
Problem 3 — Clamp
Open exercises/21/homework/03-clamp.lua. Write
clamp(x, lo, hi) that returns lo if
x is below lo, hi if above
hi, and x otherwise. Test it with three calls
covering each case.
Challenge — Swap
Open exercises/21/homework/04-swap.lua. Write
swap(a, b) that returns the two values with positions
exchanged. Then declare two variables, call swap on them,
capture the results back into the same names, and print before
and after — using both multi-return and multi-assignment from chapter
11.
Stuck or finished? Open the homework solutions page.