0Pricing
Lua Academy · Lesson

What Are Upvalues?

Understand how closures capture variables as upvalues from enclosing scopes.

What Are Upvalues? 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.

Closures Recap

A closure is a function bundled with references to variables from its enclosing scope. Those captured variables are called upvalues.

Upvalue Example

The inner function captures count from the outer function's scope.

local function makeCounter()
  local count = 0
  return function()
    count = count + 1
    return count
  end
end
local next = makeCounter()
print(next())  -- 1
print(next())  -- 2

Upvalues Are Live Variables

Upvalues are not copies — they are references to the variable. The closure can both read and write them.

Multiple Upvalues

A closure can capture multiple variables from multiple enclosing scopes.

local function adder(x)
  return function(y) return x + y end
end
local add5 = adder(5)
print(add5(3))  -- 8

Upvalue Lifetime

Upvalues live as long as any closure referencing them is alive. They are garbage collected only when all closures that reference them are collected.

debug.getupvalue

You can inspect upvalues with debug.getupvalue(fn, n) which returns the name and value of the nth upvalue.

local x = 10
local function f() return x end
print(debug.getupvalue(f, 1))  -- x  10

Upvalue vs. Global

Upvalues (locals captured by closures) are faster than globals. The VM accesses them directly via index without table lookup.

Closed Upvalue

When the enclosing block exits, the upvalue is closed: moved from the stack to the heap. The closure continues to share this heap cell.

Open vs. Closed Upvalues

Open: upvalue still on the stack (enclosing function still running). Closed: upvalue migrated to the heap when the enclosing scope ended.

Practical Use Case

Upvalues naturally implement private state in closures — a module function can keep private state without exposing it globally.

local id = 0
local function newId()
  id = id + 1
  return id
end

Upvalue Count Limit

Each Lua function can reference up to 255 upvalues. This is rarely a concern in practice.

Upvalue Question

What is an upvalue?

Recap: Upvalues

Upvalues are the closure's captured outer variables. They persist on the heap after the enclosing scope exits, are shared by reference, and provide private mutable state without globals.

Frequently asked questions

Is the “What Are Upvalues?” lesson free?

Yes — the full text of “What Are Upvalues?” 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 “What Are Upvalues?”?

Understand how closures capture variables as upvalues from enclosing scopes. 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 “What Are Upvalues?” 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. What Are Upvalues?
  2. Shared Upvalues Between Closures
  3. Factory Functions and Generators
  4. Memoization with Closures
← Back to Lua Academy