Феликс на самом деле предоставляет довольно сложную семантику, которая иногда бывает нелогичной. Замыкания захватывают контекст через указатель на рамку контекста ... в точке, где замыкания формируются. Поэтому можно ожидать, что захваченная переменная всегда отражает текущее значение переменной во время выполнения замыкания.
Это не так, потому что оптимизатор может заменить переменную на ее значение, в частности, если переменная объявлена как:
val x = 1;
оно принимается за неизменное значение, и такая замена считается безопасной. Это верно, даже если значение передается в качестве аргумента! Например:
fun f(x:int) () => x;
val y = 1;
val fy = f y; // closure formed
println$ fy();
Скорее всего, мы определили как:
val fy = fun () => 1;
было написано. В этом случае это может быть то же самое для переменной:
var z = 1;
val fz = f z;
z = 2;
println$ fz (); // prints 1 .. maybe
, заменив x значением z во время формирования замыкания, НО также может вывести 2, заменив x вместо имени переменной z.
В Феликсе не определяет , какая оптимизация применяется, и это преднамеренно: это дает компилятору свободу выбора (что он считает) наилучшей оптимизации.
Если вы хотите форсировать интерпретацию, вы можете: для аргумента параметра:
fun f (var x: int) () => x; // форсирует энергичную оценку, копирует аргумент в параметр
fun f (x: unit -> int) => x (); // заставляет ленивую оценку
И для первоначального вопроса: вы можете вызвать ленивую интерпретацию, просто используя указатель:
var x = 1;
fun f()=> *&x;
Глупо толкать энергичную интерпретацию. Если вы хотите, чтобы вы сделали это:
var x = 1;
val y = x;
var x = 2;
fun f() => y; // prints 1
Я должен сказать, что я НЕ СЧАСТЛИВ с этой семантикой, но это то, что происходит в данный момент, и это кажется вполне логичным. Что более тревожно, так это:
var g : unit -> int;
for var i = 0 upto 10 do
val x = i;
fun f()() => x;
if i == 3 do
g = f();
done
done
Цикл for плоский, без стековой рамки. Здесь «х» - это значение, но оно не является неизменным!
Если вы можете предсказать значение, напечатанное с помощью g (), то вы справляетесь лучше меня (и я разработал язык:)
К сожалению, оптимизация, полученная с помощью этой семантики, является обязательной: мы не хотим в конечном итоге получить производительность, ну, ну, в общем, Хаскелла (без обид).
Мораль этой истории такова: если ваш код зависит от ответа на вопрос ОП, от вашей головы это будет! Напишите код, в котором семантика определена, если вам требуется .