С «вызов по значению» аргументы обычно вычисляются слева направо (в большинстве языков), так что выражение будет эквивалентно что-то вроде этого:
arg1 := a // copy value of a to arg1
a := 5 // copy 5 to a
arg2 := a // copy value of a to arg2
print(arg1, arg2) // print(0, 5)
«по призванию по имени», по-видимому форма отложенной оценки, которая даст что-то вроде этого:
arg1 := function() {return a;}
arg2 := function() {a := 5; return a;}
print(arg1, arg2)
Так что в этом случае результат будет зависеть от двух вещей:
- ли на этом языке замыкания захватывают переменные по ссылке или по значению. Если захват по значению,
a := 5
не повлияет на значение a
, которое зафиксировало первое закрытие. Однако большинство языков, которые позволяют переназначить локальные переменные, реализуют захват по ссылке (например, JavaScript).
- Порядок, в котором функция
print
решает оценить свои аргументы, зависит от того, как она написана.
Если захват укупорочные по значению, print(…)
даст 0 5
, поскольку присваивание a := 5
влияет только на копию второго закрытия по a
.
Если затворы захватываются ссылкой, я могу только догадываться, на каком выходе. Но вполне вероятно, функция print
будет делать что-то вроде этого:
print := function(lazy x, lazy y) {
writeToOutput(x())
writeToOutput(y())
}
В этом случае результат будет таким же (0 5
), потому что x()
оцениваются первым, результат обрабатывается, а затем y()
оцениваются. В этом случае значение a
не изменяется до тех пор, пока функция не будет выполнена с x
.
Но это только догадка; print
может оценивать их в любом порядке (и любое количество раз).
Зависит от реализации 'print' – Bergi
Какова ваша позиция в этом вопросе? Какой материал по стратегиям оценки вы читали, что еще неясно? – Bergi
Я пишу компилятор для проекта, и кто-то сказал мне, что при вызове по-имени он будет печатать '0 5', тогда как по позывным он будет печатать' 5 5'. Его аргумент заключался в том, что при вызове по значению он сначала оценил бы все выражения и впоследствии распечатал результаты. Есть ли правда в этом? – Borimino