Functions and multiple returns

Lua · Essentials · 12 min

Functions are first-class values in Lua and the main tool for structuring code.

function add(a, b) return a + b end is sugar for assigning a function value to a variable; prefer local function add(a, b) ... end so it doesn't become a global. Functions are values: store them in tables, pass them as arguments, return them.

Arguments are positional. Missing arguments are nil and extra ones are dropped, so a = a or 1 is the usual way to give a default.

A function can return multiple values: return q, r. The caller receives as many as it asks for. The adjustment rule matters: a call returns all its values only when it is the last expression in a list. In the middle, or wrapped in parentheses, it is cut to one value.

Variadic functions use .... Inside, select("#", ...) counts the arguments (including nils) and {...} or table.pack(...) collects them; table.unpack(t) does the reverse, spreading a table into arguments.

When a function takes a single table or string literal, you can drop the parentheses: f{x = 1} and print "hi". The table form is a common way to fake named arguments.

Lua performs proper tail calls: return f(x) reuses the stack frame, so tail-recursive loops never overflow.

Example

local function divmod(a, b)
  return a // b, a % b
end
local q, r = divmod(17, 5)
print(q, r)                    --> 3	2
print(divmod(17, 5), "end")    --> 3	end (cut to one value)
print((divmod(17, 5)))         --> 3

local function sum(...)
  local total = 0
  for _, v in ipairs({...}) do total = total + v end
  return total, select("#", ...)
end
print(sum(1, 2, 3))            --> 6	3
print(sum(table.unpack({4, 5}))) --> 9	2

local function greet(opts)
  local name = opts.name or "world"
  return "hello " .. name
end
print(greet{name = "Ana"})     --> hello Ana

Remember

  • Use local function so functions don't become globals
  • A call expands to all its results only as the last item in a list
  • ..., select("#", ...) and table.unpack handle varargs
  • f{...} with a table fakes named arguments

Watch out for

  • Expecting f(), x to keep all of f's return values; only the last call expands.

Check yourself

  1. local function two() return 1, 2 end. What does print(two(), 9) print?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.lua.org/manual/5.4/manual.html#3.4.11