Menu
Coddy logo textTech

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: 3

When 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 icon

Challenge

Easy

Write 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 createMultiplier that takes a number parameter
  • The nested function should multiply its parameter by the factor from the outer function
  • The nested function will form a closure, remembering the factor value
  • Call the multiplier function with the number parameter and return the result

Parameters:

  • factor (number): The multiplier value
  • number (number): The number to multiply

Returns:

  • The result of multiplying number by factor (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: 3

When 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

end
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Logic & Flow