🎓 A1Learner
🔍
0 of 52 lessons completed

Lua Closures with State

A closure with state is a function returned by another function that keeps its own local variables alive after the outer call ends. Each returned function has its own set of those variables.

A returned function keeps its count

The factory makes a counter. Each call moves the count by one.

local function make_counter()
  local count = 0
  return function()
    count = count + 1
    return count
  end
end
local count_up = make_counter()
print(count_up())
print(count_up())
print(count_up())

Two counters do not share state

Two calls to the factory make two counters. Their counts move on their own.

local function make_counter()
  local count = 0
  return function()
    count = count + 1
    return count
  end
end
local a = make_counter()
local b = make_counter()
print(a())
print(a())
print(b())
print(a())

A factory argument sets the start

The factory can take a start value. The first call then adds one to that start.

local function make_counter(start)
  local count = start
  return function()
    count = count + 1
    return count
  end
end
local count_from_ten = make_counter(10)
print(count_from_ten())
print(count_from_ten())
local count_from_hundred = make_counter(100)
print(count_from_hundred())

Example

local function make_counter(start, step)
  local count = start
  return function()
    count = count + step
    return count
  end
end
local a = make_counter(0, 2)
local b = make_counter(10, 5)
print(a())
print(a())
print(b())
print(a())
print(b())

Key points

  • Upvalue: a local variable from an outer function that an inner function keeps using.
  • Factory: a function that builds and returns a new function each time it runs.
  • Fresh state: each call to a factory gives the new function its own separate variables.
  • Counter step: calling the returned function changes only its own stored count.
  • Start value: a factory argument that sets the first value of the new state.

In this example, the factory takes a start value and a step value and returns a function that adds the step to its own count. Counter a starts at 0 and steps by 2, while counter b starts at 10 and steps by 5. The prints show a at 2 and 4, then b at 15, then a again at 6, then b at 20, so each counter keeps its own state.

Note

Lua functions are values, so a factory can return a function just like it returns a number.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A factory makes a counter that starts at 0 and adds 1 on each call. You make counter a, call it twice, then make counter b and call it once. What does the call to b return?