Ответ 1
Вызов по имени немного отличается от вашего описания. В псевдокоде представьте:
function foo(index, value-increment)
sum = 0
loop index = 1 to 3
sum = sum + value-increment
return sum
x = 3
foo(x, 1 / x)
Если наш вызов foo
по ссылке, второй аргумент 1 / x
оценивается только один раз, давая нам эффективно: 1/3 + 1/3 + 1/3. Это строгая оценка - каждый аргумент полностью оценивается до применения функции.
Если мы вызываем по имени, 1 / x
строго не оценивается. Вместо этого он оценивался в цикле по мере необходимости. Эффективно цикл становится:
loop x = 1 to 3
sum = sum + 1 / x
или 1/1 + 1/2 + 1/3.
Взгляните на thunks, хотя thunks не всегда означает call-by-name. Haskell имеет идею thunks, но использует call-by-need, где 1 / x
не будет оцениваться до тех пор, пока это не понадобится, но затем будет оценено только один раз (не говоря уже о том, что Haskell не будет иметь изменяемую переменную цикла).
Другие ресурсы: