Разница между Call-By-Name и Call-By-Reference

Методы передачи параметров:

Из того, что я могу собрать по этим двум методам.

Вызов по ссылке:

Расположение адреса переменной передается в функцию, поэтому в локальной области действия функции любые изменения значения локальной переменной изменят значение исходной переменной, так как они указывают на то же самое место.

Вызов по имени:

Действительная переменная передается в функцию. Любые изменения значения переменной внутри локальной области действия функции также будут отображаться вне функции.

Мне кажется, эти два метода передачи параметров выполняют одно и то же? Оба они действуют на исходное содержимое переменных. У меня есть неправильные определения? Думаю ли я об этом неправильно?

Ответ 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 не будет иметь изменяемую переменную цикла).

Другие ресурсы: