Closures in Lua

Lua supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.

-- This function intSeq returns another function, which
-- we define anonymously in the body of intSeq. The
-- returned function closes over the variable i to
-- form a closure.
function intSeq()
    local i = 0
    return function()
        i = i + 1
        return i
    end
end

-- In the main part of our script
local function main()
    -- We call intSeq, assigning the result (a function)
    -- to nextInt. This function value captures its
    -- own i value, which will be updated each time
    -- we call nextInt.
    local nextInt = intSeq()

    -- See the effect of the closure by calling nextInt
    -- a few times.
    print(nextInt())
    print(nextInt())
    print(nextInt())

    -- To confirm that the state is unique to that
    -- particular function, create and test a new one.
    local newInts = intSeq()
    print(newInts())
end

main()

To run the script, save it as closures.lua and use the Lua interpreter:

$ lua closures.lua
1
2
3
1

In this Lua example, we’ve created a closure that generates a sequence of integers. The intSeq function returns an anonymous function that increments and returns a counter. Each time we call intSeq(), we get a new function with its own separate counter.

The main function demonstrates how to use this closure. We create a nextInt function by calling intSeq(), and then call it multiple times to see the counter increment. We also create a second function newInts to show that it has its own separate state.

This example showcases Lua’s support for first-class functions and closures, which are powerful features for creating flexible and maintainable code.

The last feature of functions we’ll look at for now is recursion.