Какова правильная семантика замыкания над переменной цикла? [закрыто]
Рассмотрим следующий код lua:
f = {}
for i = 1, 10 do
f[i] = function()
print(i .. " ")
end
end
for k = 1, 10 do
f[k]()
end
Это печатает числа от 1 до 10. В этом случае,i
закрывается по значению для каждой итерации внешнего цикла. Так я всегда понимал замыкания и был очень счастлив ...
... пока я не портировал некоторый код lua на c # и не попытался сделать то же самое:
var f = new Action[10];
for (int i = 0; i < 10; i++)
{
f[i] = (new Action(delegate()
{
Console.Write(i + " ");
}));
}
for (int k = 0; k < 10; k++)
{
f[k]();
}
И теперь я получаю число 10 напечатано 10 раз (пустьзабудем, что массивы lua основаны на 1). На самом деле бывает, что в этом случае замыкание работает над переменной, а не над ее значением, что имеет большой смысл, так как яЯ вызываю функции только после окончания первого цикла.
Кажется, что JavaScript имеет ту же семантику (близко к переменной):
var f = []
for (var i = 0; i < 10; i++)
{
f[i] = function()
{
document.write(i + ' ');
};
}
for (var k = 0; k < 10; k++)
{
f[k]();
}
На самом деле, оба поведения имеют большой смысл, но, конечно, несовместимы.
Если есть "правильный" способ сделать это, то либо lua, либо c # и JavaScript не правы (у меня нетпробовал еще с другими языками). Итак, мой вопрос:Какие "правильный" семантика закрытия переменной внутри цикла? "
редактировать: яя не спрашиваю, какисправить» этот. Я знаю, что могу добавить локальную переменную внутри цикла и закрыть ее, чтобы получить поведение lua в c # / JavaScript. Я хочу знать, каково теоретически правильное значение закрытия по зацикленной переменной и бонусные баллы за короткий список языков, которые реализуют замыкания в каждом случае.
редактировать: перефразировать мой вопрос: "Каково поведение закрытия по зацикленной переменной в лямбда-исчислении? "