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! again

Read 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 = 7

Missing 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 ignored

return — 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)       -- 10

return 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  2

This 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))   -- 7

No 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())   -- 1

Every 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())   -- 3

It 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.