Learn Lua in Neovim: Functions — Basics, Parameters vs Arguments & return | Episode 12
Video: Learn Lua in Neovim: Functions — Basics, Parameters vs Arguments & return | Episode 12 by Taught by Celeste AI - AI Coding Coach
Lua Functions: Basics, Parameters vs Arguments, and return
function name(params) ... endto define.name(args)to call.return valueto send a result back. Parameters are placeholders; arguments are the actual values you pass in.
Functions package up code so you can call it many times with different inputs. They're the second pillar of Lua programs (after tables, which we'll meet in episode 17).
Defining a function
function greet(name)
print("Hello, " .. name .. "!")
end
greet("Alice")
greet("Bob")
greet("Lua")
Output:
Hello, Alice!
Hello, Bob!
Hello, Lua!
Three keywords:
function— start a function definition.function name(params)— give it a name and a parameter list.end— close the body.
name is the function. params is the parameter list. The body runs each time the function is called.
Parameters vs arguments
The terms get confused, but they're different:
- Parameters are the names in the function definition.
nameinfunction greet(name). - Arguments are the values you pass when calling.
"Alice"ingreet("Alice").
Inside the function, the parameter holds the argument's value:
function greet(name)
-- here, `name` is "Alice" if called with greet("Alice")
end
The names parameter and argument carry meaning when reading docs. "Function takes two parameters" describes the signature; "we passed three arguments" describes a call.
Return values
function add(a, b)
return a + b
end
local result = add(10, 20)
print("10 + 20 = " .. result)
print("3 + 7 = " .. add(3, 7))
return value sends a value back. The caller receives it as the function call's value.
add(3, 7) evaluates to 10. You can use it in expressions like any other value.
Functions without return
function greet(name)
print("Hello, " .. name)
end
local x = greet("Alice")
print(x) -- nil
A function that doesn't return anything implicitly returns nil. This is fine for "do something" functions like greet.
return exits the function
function describe(n)
if n == 0 then
return "zero"
end
if n > 0 then
return "positive"
end
return "negative"
end
return immediately exits — once you've returned, the rest of the body is skipped. Useful for early exits and guard clauses:
function safe_divide(a, b)
if b == 0 then return nil end
return a / b
end
A boolean function
function is_even(n)
return n % 2 == 0
end
print("4 is even: " .. tostring(is_even(4)))
print("7 is even: " .. tostring(is_even(7)))
The body is one expression: n % 2 == 0. Lua evaluates it (true or false) and return sends the boolean back.
tostring(...) is needed because .. only auto-converts numbers, not booleans.
Local functions
local function square(x)
return x * x
end
Just like variables, prefer local function to plain function (which creates a global). The forward-decl idiom for recursive locals:
local fact
fact = function(n)
if n <= 1 then return 1 end
return n * fact(n - 1)
end
The two-step is needed because at the moment local fact = function(n) ... fact(n-1) ... end is parsed, fact doesn't exist yet on the right side. Splitting it lets the body see the local.
Or use the cleaner:
local function fact(n)
if n <= 1 then return 1 end
return n * fact(n - 1)
end
local function desugars to "declare local first, assign function second" — handles the recursion automatically.
Functions as values
In Lua, functions are first-class: you can store them in variables, pass them as arguments, return them from other functions. Episode 15 dives into this; for now, just know:
local op = add -- store a reference
print(op(2, 3)) -- 5
local fn = function(x) return x * 2 end -- anonymous function
print(fn(10)) -- 20
Default parameter values
Lua doesn't have built-in default values, but the or idiom from episode 8 covers the common case:
function greet(name)
name = name or "stranger"
print("Hello, " .. name)
end
greet() -- Hello, stranger
greet("Alice") -- Hello, Alice
For multiple defaults:
function rect(width, height, color)
width = width or 10
height = height or 5
color = color or "blue"
-- ...
end
Verbose but clear.
Missing arguments are nil
function describe(name, age)
print(name) -- "Alice"
print(age) -- nil
end
describe("Alice")
Lua doesn't error on missing arguments — they're just nil. That's why the or default trick works.
Conversely, extra arguments are silently dropped:
function add(a, b)
return a + b
end
add(1, 2, 3) -- returns 3; the third arg is ignored
Common stumbles
Forgetting return. A function that should produce a value but only prints it returns nil. Make sure to return if the caller needs the result.
Using the function before defining it. Lua reads top-to-bottom; calling greet("Alice") before function greet is defined returns nil (and crashes when you try to call it).
Confusing parameters and arguments. Parameters are named in the definition; arguments are values at the call site. A function "takes parameters" but "is called with arguments."
Forgetting local function. Plain function name(...) creates a global. Subtle bug source. Always local function.
Recursion without forward declaration. local fact = function(n) ... fact(...) ... end has fact undefined inside the body. Use local function fact(n) ... end or the two-step idiom.
What's next
Episode 13: multiple returns and variadics. Lua functions can return more than one value (return a, b), and accept variable numbers of arguments (function f(...)).
Recap
function name(params) body end to define; local function for non-globals. Parameters are placeholders, arguments are values. return value sends a result back; missing return = nil. Missing arguments are nil; extra arguments are ignored. Functions are first-class values — store them, pass them, return them. Default parameters via param = param or default.
Next episode: multiple returns and variadics.