Skip to content

Instantly share code, notes, and snippets.

@graue
Last active December 14, 2015 11:29
Show Gist options
  • Save graue/5079734 to your computer and use it in GitHub Desktop.
Save graue/5079734 to your computer and use it in GitHub Desktop.
Weirdness with JS closures (Lua behaves differently).
NOTE: Scroll down for explanation (the difference turns out to be scoping, not closures per se).
$ cat juices.lua
local fruits = {"apple", "orange", "grape"}
local juicers = {}
for i,v in ipairs(fruits) do
local fruit = v
juicers[i] = function() return fruit .. " juice" end
end
print(juicers[1]());
print(juicers[2]());
print(juicers[3]());
$ lua juices.lua
apple juice
orange juice
grape juice
$ cat juices.js
var fruits = ["apple", "orange", "grape"];
var juicers = [];
for (var i in fruits) {
var fruit = fruits[i];
juicers[i] = function() { return fruit + " juice"; }
}
console.log(juicers[0]());
console.log(juicers[1]());
console.log(juicers[2]());
$ node juices.js
grape juice
grape juice
grape juice
@graue
Copy link
Author

graue commented Mar 4, 2013

So closures actually work the same way in Lua as in JavaScript and Python. If you write the loop like this in Lua:

local fruit = ""
for i,v in ipairs(fruits) do
    fruit = v
    juicers[i] = function() return fruit .. " juice" end
end

print(juicers[1]());
print(juicers[2]());
print(juicers[3]());

...you again get "grape juice" three times. None of the 3 languages are copying variables when they create a closure. In all three languages, the closure references the original variable, which can change.

But in Lua, a new variable called v is created in each iteration of the loop; it doesn't update the old v. Likewise in the code up top, a new local variable called fruit was created on each iteration of the loop. In this version here we had to explicitly override that behavior. Closures are the same between Lua and JS/Python; scoping is not.

@dschobel
Copy link

dschobel commented Mar 4, 2013

yeah, so long story short, block scoping makes the world sane and python and javascript are inferior for not having it. that's my conclusion to all this :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment