Back to Blog

Lua with Neovim: Closures — Upvalues, Counter Factory & Functions That Remember | Episode 16

Sandy LaneSandy Lane

Video: Lua with Neovim: Closures — Upvalues, Counter Factory & Functions That Remember | Episode 16 by Taught by Celeste AI - AI Coding Coach

Watch full page →

Lua with Neovim: Closures — Upvalues, Counter Factory & Functions That Remember

Closures in Lua allow functions to capture and remember variables from their surrounding scope, known as upvalues. This enables the creation of factory functions like make_counter() and make_multiplier(factor), which produce independent functions that maintain their own private state without relying on globals.

Code

-- Factory function that returns a counter closure
function make_counter()
  local count = 0  -- upvalue: private state remembered by the closure
  return function()
    count = count + 1
    return count
  end
end

-- Create two independent counters
local counter_a = make_counter()
local counter_b = make_counter()

print(counter_a())  -- 1
print(counter_a())  -- 2
print(counter_b())  -- 1 (independent state)
print(counter_a())  -- 3

-- Factory function that returns a multiplier closure
function make_multiplier(factor)
  return function(x)
    return x * factor  -- 'factor' is an upvalue captured by the closure
  end
end

local double = make_multiplier(2)
local triple = make_multiplier(3)

print(double(5))  -- 10
print(triple(5))  -- 15
print(double(10)) -- 20

Key Points

  • A closure is a function that captures and remembers variables from its enclosing scope, called upvalues.
  • Each call to a factory function returns a new closure with its own independent copy of upvalues.
  • Multiple closures created by the same factory do not share state, ensuring encapsulation.
  • Closures provide a clean alternative to globals for maintaining private, persistent state in Lua.
  • Parameterized closures like make_multiplier(factor) allow flexible, reusable function factories.