Int[] ns := [,]
|->|[] fs := [,]
for (Int i := 0; i < 10; ++i) {
ns.add(20 + i)
}
for (Int i := 0; i < 10; ++i) {
Int n := ns[i]
fs.add() |->| { echo(n) }
}
fs.each { it() }
It prints 20..29 on Java (as intended). But on JavaScript it prints 29 ten times.
P.S. If each() is used instead of the second for, everything works fine.
vkuzkokovThu 31 Mar 2011
It has to do with JS crazy variable scopes. This code
for (var i = 0; i < 10; ++i)
{
var n = ns.get(i);
fs[i] = function() { print(n) };
}
is close enough to what compiler generates. In JS n doesn't go out of visibility until we return from current function. each works because it calls a function on every iteration and thus creates a new scope each time.
Possible solution would be to generate something like
for (var i = 0; i < 10; ++i)
function()
{
var n = ns.get(i);
fs[i] = function() { print(n) };
}();
Workaround is to stick to each and keep in mind JS variable scopes when using closures.
andyThu 31 Mar 2011
Promoted to ticket #1468 and assigned to andy
Can be tricky - but I should be able to fix that in the compiler.
dsav Thu 31 Mar 2011
Please, consider the following code:
It prints 20..29 on Java (as intended). But on JavaScript it prints 29 ten times.
P.S. If
each()
is used instead of the secondfor
, everything works fine.vkuzkokov Thu 31 Mar 2011
It has to do with JS crazy variable scopes. This code
is close enough to what compiler generates. In JS
n
doesn't go out of visibility until we return from current function.each
works because it calls a function on every iteration and thus creates a new scope each time.Possible solution would be to generate something like
Workaround is to stick to
each
and keep in mind JS variable scopes when using closures.andy Thu 31 Mar 2011
Promoted to ticket #1468 and assigned to andy
Can be tricky - but I should be able to fix that in the compiler.