0Pricing
Lua Academy · Lesson

Defining and Calling Functions

Syntax for function declaration, calling conventions, and local vs global functions.

Defining and Calling Functions is a free Lua Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Lua Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Function Syntax

Functions in Lua are defined with the function keyword. The body is a block terminated by end. Functions can be global or local. You call a function by appending parentheses with arguments. If you omit arguments, missing parameters receive nil.

function sayHello(name)
  print("Hello, " .. (name or "World") .. "!")
end

sayHello("Lua")   -- Hello, Lua!
sayHello()        -- Hello, World!

local function add(a, b)
  return a + b
end
print(add(3, 4))  -- 7

Return Values

Functions return values with return. Unlike most languages, Lua functions can return multiple values. If you don't explicitly return, the function returns nothing (zero values). Excess return values are discarded when the call is not the last expression in a list.

local function minMax(t)
  local lo, hi = t[1], t[1]
  for i = 2, #t do
    if t[i] < lo then lo = t[i] end
    if t[i] > hi then hi = t[i] end
  end
  return lo, hi
end

local lo, hi = minMax({5,2,8,1,9})
print(lo, hi)  -- 1  9

Function as Value

Functions are first-class values in Lua. You can store them in variables, pass them as arguments to other functions, and return them. This enables callbacks, higher-order functions, and functional programming patterns.

local ops = {
  add = function(a, b) return a + b end,
  sub = function(a, b) return a - b end,
  mul = function(a, b) return a * b end,
}

local function apply(op, a, b)
  return op(a, b)
end

print(apply(ops.add, 10, 3))  -- 13
print(apply(ops.mul, 4, 5))   -- 20

Local vs Global Functions

Use local function for module-private helpers. Global functions pollute the global namespace and are accessible from anywhere, which can cause naming conflicts. In most cases, prefer local functions and only expose what you need through a module table.

-- Bad: pollutes global namespace
function helper() end

-- Good: module-local
local function helper()
  return "I am local"
end

-- Module export pattern
local M = {}
function M.publicFunc()
  return helper()  -- can call local
end
return M

Methods with Colon Syntax

Lua provides syntactic sugar for defining and calling methods on tables. obj:method(arg) is equivalent to obj.method(obj, arg). The colon form implicitly passes the table as the first argument, conventionally named self.

local Dog = {}
Dog.__index = Dog

function Dog.new(name)
  return setmetatable({name=name}, Dog)
end

function Dog:speak()
  print(self.name .. " says: Woof!")
end

local d = Dog.new("Rex")
d:speak()   -- Rex says: Woof!

Optional Parameters Pattern

Lua has no built-in optional parameters, but you can simulate them with nil checks. Pass a single options table for functions with many optional parameters — this is cleaner than a long argument list.

local function createUser(name, opts)
  opts = opts or {}
  return {
    name = name,
    role = opts.role or "user",
    active = opts.active ~= false,
    score = opts.score or 0,
  }
end

local u = createUser("Alice", {role="admin", score=100})
print(u.name, u.role, u.score)

Tail Calls

A tail call is a function call in the tail position (the last action before returning). Lua performs tail call optimization: a proper tail call does not use extra stack space. This enables deep recursion without stack overflow when the recursive call is in tail position.

local 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(10))  -- 3628800
-- Can handle very large n without stack overflow

Immediately Invoked Functions

You can define and call a function immediately: (function() ... end)(). This is useful to create a local scope, execute setup code exactly once, or avoid polluting the outer scope with temporary variables.

local result = (function()
  local temp = 100
  local adjusted = temp * 1.5
  return math.floor(adjusted)
end)()

print(result)   -- 150
-- temp and adjusted not visible here

Storing Functions in Tables

Storing functions in tables is idiomatic Lua module design. The table acts as a namespace. You define functions by assigning them to table fields or using dot/colon notation with the table name.

local math2 = {}

function math2.clamp(val, lo, hi)
  return math.max(lo, math.min(hi, val))
end

function math2.lerp(a, b, t)
  return a + (b - a) * t
end

print(math2.clamp(150, 0, 100))  -- 100
print(math2.lerp(0, 10, 0.5))   -- 5.0

Closures as Callbacks

Higher-order functions accept callbacks. In Lua, callbacks are just function values. Closures are especially useful as callbacks because they capture the calling context without needing to pass extra arguments through the higher-order function.

local function forEach(t, fn)
  for i, v in ipairs(t) do
    fn(v, i)
  end
end

local sum = 0
forEach({10, 20, 30}, function(v)
  sum = sum + v
end)
print(sum)   -- 60

forEach({"a","b","c"}, function(v, i)
  print(i, v)
end)

Quick Check

What is the output of: local function f() return 1, 2, 3 end; local a, b = f()?

Recap: Functions

Key points:

  • Use local function to avoid polluting globals
  • Functions are first-class: store in variables, tables, pass as args
  • Colon syntax implicitly passes self
  • Simulate optional params with opts or {}
  • Tail calls avoid stack overflow in deep recursion
  • Immediately invoked functions create isolated scopes

Frequently asked questions

Is the “Defining and Calling Functions” lesson free?

Yes — the full text of “Defining and Calling Functions” is free to read here on the web, and the Lua Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Lua Academy course, upgrade to CoddyKit PRO.

What will I learn in “Defining and Calling Functions”?

Syntax for function declaration, calling conventions, and local vs global functions. You practise Lua Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Lua Academy?

No prior experience is required. Lua Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Defining and Calling Functions” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Lua Academy lesson?

Yes. Every Lua Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Defining and Calling Functions
  2. Multiple Return Values
  3. Varargs and the ... Operator
  4. Recursion in Lua
← Back to Lua Academy