Friday, September 20, 2013

Closure

Lua and Javascript are surprisingly similar languages, as I was happy to learn (coming from a Javascript background). Both of them are very loose in handling data types, don't require classes, and have a nice feature called closure. That's by no means an exhaustive list of similarities, of course. However, today I thought I'd write about some differences in how each of them handles closure. Take a look at the two code samples below:

Lua:
 
function main()
    local printFunctions={}
    local i,j
    for i=1,10 do
        local printi = function()
            print(i)
        end
        printFunctions[i]=printi
    end
    for j=1,10 do
        printFunctions[j]()
    end
end

main()

Javascript:
function main()
{
    var printFunctions=[]
    var i,j
    for(i=0;i<10;i++)
    {
        var printi = function()
        {
            console.log(i);
        }
        printFunctions[i]=printi
    }
    for(j=0;j<10;j++)
    {
        printFunctions[j]()
    }
}

main()

Both of these would appear to be identical. They create 10 functions which simply print the value of i. Then, each of the functions is called. You would expect the result to be "0 1 2 3 4 5 6 7 8 9," right? That's correct in Lua, but not for Javascript. Javascript prints "10 10 10 10 10 10 10 10 10 10."

UPDATE:
The following explanation is not accurate. See this Stack Overflow question for details.

Inaccurate explanation:
So why does this occur? It occurs because Lua and Javascript handle closure in different ways. Lua treats the closure as part of the function reference itself (see this reference), and therefore each time you create a function reference you get a new copy of the variable. The function is created 10 times, with i having values from 0 to 9 during those initializations, and therefore the numbers 0 to 9 are printed.

Javascript, on the other hand, creates a closure based on the variable declarations (see this reference). Since i was declared in the main function, i can only have one value for each time the main function was called. The main function was only called once, so i has only one value, and that value is 10 at the point when the functions are called.

Perhaps this is better explained with another example. What if we changed the anonymous function to print j instead of i? In Lua, nil is printed 10 times because at the point where the function is declared, j is nil. By contrast, in Javascript, the numbers 0 through 9 are printed, because at the point where the function is called, the j from the main function ranges from 0 to 9.

Hopefully that was helpful to anybody else familiar with Javascript and trying to learn Lua. If anybody else has a better way of explaining the difference, please feel free to leave a comment.

No comments:

Post a Comment