Подтвердить что ты не робот

Что такое "проход по имени" и как он работает?

Я проверяю википедию и googled, но я до сих пор не могу окунуться в то, как пропуски по имени работают в ALGOL 60.

4b9b3361

Ответ 1

Я нашел хорошее объяснение в Pass-By-Name Parameter Passing. По сути, тело функции интерпретируется во время вызова после текстовой подстановки фактических параметров в тело функции. В этом смысле метод оценки аналогичен методу макросов препроцессора C.

Подставляя фактические параметры в тело функции, тело функции может считывать и записывать заданные параметры. В этом смысле метод оценки аналогичен методу pass-by-reference. Разница в том, что, поскольку с пропущенным именем параметр оценивается внутри функции, параметр, такой как a[i], зависит от текущего значения i внутри функции, вместо того, чтобы ссылаться на значение в a[i] до функция была вызвана.

На странице, приведенной выше, есть еще несколько примеров того, как pass-by-name полезен и опасен. Методы, сделанные возможным путем переадресации, в значительной степени сегодня заменяются другими, более безопасными методами, такими как передача по ссылке и лямбда-функции.

Ответ 2

Я предполагаю, что вы имеете в виду call-by-name в ALGOL 60.

Вызов по имени, похожий на call-by-reference, в котором вы можете изменить значение переданного параметра. Он отличается от вызова по ссылке тем, что параметр не оценивается до того, как вызывается процедура, но вместо этого оценивается лениво. То есть, он оценивается тогда и только тогда, когда фактически используется параметр.

Например, предположим, что у нас есть процедура f (x, y), и мы передаем ее я и i/2, где я изначально равно 10. Если f устанавливает x в 42 и затем вычисляет y, он увидит значение 21 (тогда как с вызовом по ссылке или вызовом по значению все равно будет видно 5). Это происходит потому, что выражение "i/2" не оценивается до тех пор, пока не будет оценено значение y.

По-видимому, это ведет себя как буквальная подстановка параметров (с переименованием во избежание конфликтов имен). На практике, однако, это реализовано с использованием "thunks" (в основном закрытий) для переданных в выражениях.

Статья в Википедии о Jensen Device показывает интересный пример использования вызова по имени. В частности, обратите внимание на то, как используется параметр "term".

Ответ 3

Для тех, кто в будущем:

Понятия на языках программирования Джон К. Митчелл был также полезен.

Pass-по-Name. Возможно, самый странный особенность Алгола 60, в ретроспективе, использование pass-by-name. В pass-by-name, результат вызов процедуры такой же, как если бы формальный параметр были заменены на тело процедуры. Это правило для определения результата процедуры вызов путем копирования процедуры и заменяя формальные параметры называется правилом копирования Algol 60. Хотя правило копирования хорошо работает для чистых функциональных программ, так как иллюстрируется β-восстановлением в лямбда исчисление, взаимодействие со стороной эффекты к формальному параметру являются немного странно. Вот пример программа, показывающая упомянутую технику как устройство Дженсена: передача выражение и переменная, содержащая к процедуре, чтобы процедура может использовать один параметр для изменения местоположение, на которое ссылается другое:


 begin integer i;
        integer procedure sum(i, j);
            integer i, j;
                comment parameters passed by name;
            begin integer sm; sm := 0;
                for i := 1 step 1 until 100 do sm := sm + j;
                sum := sm
            end;
        print(sum(i, i*10 ))

конец

В этой программе процедура sum (i, j) добавляет значения j как я идет от 1 до 100. Если вы посмотрите на кода, вы поймете, что процедура не имеет смысла, если изменения в я приводят к некоторым изменениям в значение j; в противном случае процедура просто вычисляет 100 * j. В вызове sum (i, я * 10), показанная здесь, цикл for в сумме суммируется сумма сумм значение я * 10 при я идет от 1 до 100.

Ответ 4

У Flatlander есть иллюстративный пример того, как он работает в Scala здесь. Предположим, что вы хотели реализовать while:

def mywhile(condition: => Boolean)(body: => Unit): Unit =
  if (condition) {
    body
    mywhile(condition)(body)
  }

Мы можем назвать это следующим образом:

var i = 0
mywhile (i < 10) {
  println(i)
  i += 1
}

Scala не Algol 60, но, возможно, он проливает некоторый свет.

Ответ 5

Вы можете передать "имя" в символической форме переменной, которая позволяет одновременно обновлять и получать доступ. В качестве примера можно сказать, что вы хотите втрое изменить переменную x, которая имеет тип int:

start double(x);
real x;
begin
x : = x * 3
end;

Ответ 6

ALGOL был разработан для математических алгоритмов. Мне нравится функция суммирования в качестве примера вызова по имени.

Извините, мой ALGOL немного ржавый, синтаксис, вероятно, не прав.

.FUNCTION SUM(var,from,to,function)
.BEGIN
  .REAL sum =0;
  .FOR var = from .TO to .DO sum = function;
  return sum;
.END

Вы можете использовать сумму, например

  Y = sum(x,1,4,sum(y,3,8,x+y));

В приведенной выше внутренней сумме (y, 3,8, x + y) будет генерировать неназванную функцию для перехода к внешнему вызову суммы. Переменные x и y не передаются по значению, а по имени. В случае переменных вызов по имени эквивалентен вызову по адресу адреса в C. Он немного запутывается при рекурсии.

Borrows изготовили машины ALGOL. У них была 48-битная память слов с тремя флагами. Биты флагов реализовали cal по имени ALGOL. это была машина стека, поэтому, когда функция была загружена в стек, вызов по имени fag заставил бы его вызываться. Компилятор будет генерировать неназванные функции, когда выражения используются в качестве аргументов. Переменная была бы простой косвенной ссылкой. Возникла ошибка при записи функции.

Ответ 7

На самом деле, звоните по имени, это не просто историческое любопытство. Вы можете выполнять вызовы по имени в командных файлах Windows (и множество других языков сценариев). Знание того, как это работает, и как эффективно использовать его в программировании, могут открыть аккуратные решения проблем. Я знаю, что это только передача строк для последующего расширения, но с ним можно манипулировать, чтобы иметь похожие эффекты, такие как call-by-name.

call :assign x 1
exit /b
:assign
setlocal enabledelayedexpansion
(endlocal
:: Argument 1 is the name of the variable
set %1=%2
)
exit /b

Ответ 8

Я знаю, что присоединяюсь к клубу поздно, и это не обязательно ответ, но я хотел добавить одну вещь, которая могла бы помочь прояснить ситуацию. Я всегда думал о Algol pass-by-name как о том же процессе, когда директивы препроцессора С++ (в частности, макросы) заменяют имя некоторой функции/переменной фактическим куском кода во время компиляции. Переадресация по сути заменяет имя формального параметра фактическим параметром и выполняет его. Я никогда не писал в Algol, но я слышал, что pass-by-name будет иметь тот же результат, что и С++ pass-by-reference.