Какова правильная семантика замыкания над переменной цикла? [закрыто]

Рассмотрим следующий код 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. Я хочу знать, каково теоретически правильное значение закрытия по зацикленной переменной и бонусные баллы за короткий список языков, которые реализуют замыкания в каждом случае.

редактировать: перефразировать мой вопрос: "каково поведение закрытия по зацикленной переменной в лямбда-исчислении?"

Ответы на вопрос(4)

Ваш ответ на вопрос