What is a Closure?
Part of the Logic & Flow section of Coddy's Lua journey — lesson 14 of 54.
You've learned that functions can be stored in variables, passed as arguments, and returned from other functions. Now we'll explore one of the most powerful consequences of this: closures.
A closure occurs when a nested function "remembers" the local variables from its enclosing function, even after that outer function has finished executing. This might sound strange at first—how can a variable still exist after the function that created it is done?
Here's a simple example that demonstrates this concept:
function createCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = createCounter()
print(counter()) -- Output: 1
print(counter()) -- Output: 2
print(counter()) -- Output: 3When createCounter() is called, it creates a local variable count and returns an anonymous function. Normally, you'd expect count to disappear once createCounter() finishes. But the returned function still has access to count—it "closes over" that variable.
Each time you call counter(), it accesses and modifies the same count variable that was created when createCounter() first ran. The inner function carries its environment with it, preserving the state between calls.
Challenge
EasyWrite a function createMultiplier that creates a multiplier function with a specific factor, then immediately uses it to multiply a given number.
Logic:
- Create a nested function inside
createMultiplierthat takes a number parameter - The nested function should multiply its parameter by the
factorfrom the outer function - The nested function will form a closure, remembering the
factorvalue - Call the multiplier function with the
numberparameter and return the result
Parameters:
factor(number): The multiplier valuenumber(number): The number to multiply
Returns:
- The result of multiplying
numberbyfactor(number)
Cheat sheet
A closure occurs when a nested function "remembers" the local variables from its enclosing function, even after that outer function has finished executing.
The inner function carries its environment with it, preserving the state between calls:
function createCounter()
local count = 0
return function()
count = count + 1
return count
end
end
local counter = createCounter()
print(counter()) -- Output: 1
print(counter()) -- Output: 2
print(counter()) -- Output: 3When createCounter() is called, it creates a local variable count and returns an anonymous function. The returned function still has access to count—it "closes over" that variable, even after the outer function finishes executing.
Try it yourself
function createMultiplier(factor, number)
local multiply = function(x)
return x * factor
end
-- Use multiply function below
endThis lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Advanced Table Iteration
Iterating with pairs()Iterating with ipairs()pairs() vs. ipairs()Recap - Character Sheet2More Table Library Functions
table.concat()table construction & unpack()table.sort()Custom Sorting with FunctionsRecap - High Score Board3Advanced Function Concepts
Returning Multiple ValuesVariadic Functions (...)Functions First-Class ValuesAnonymous FunctionsWhat is a Closure?Recap - Simple Event Handler