Что такое “передача по имени” и как она работает точно?

Вам будет лучше с шаблоном

Например, шаблон hosts.j2

127.0.0.1                localhost
{% for item in my_hosts %}
{{ item }}
{% endfor %}

с playbook

- hosts: localhost
  vars:
    my_hosts:
      - 10.1.0.1 ac1.example.com ac1
      - 10.1.0.2 ac2.example.com ac2
      - 10.1.0.3 ac3.example.com ac3
  tasks:
    - template:
        src: hosts.j2
        dest: /etc/hosts

дает

> cat /etc/hosts
127.0.0.1                localhost
10.1.0.1 ac1.example.com ac1
10.1.0.2 ac2.example.com ac2
10.1.0.3 ac3.example.com ac3

35
задан Suncatcher 11 November 2019 в 00:06
поделиться

4 ответа

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

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

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

37
ответ дан 27 November 2019 в 07:05
поделиться

I'm assuming you mean call-by-name in ALGOL 60.

Call-by-name is similar to call-by-reference in that you can change the value of the passed in parameter. It differs from call-by-reference in that the parameter is not evaluated before the procedure is called but is instead evaluated lazily. That is, it is evaluated when and only when the parameter is actually used.

For example, suppose we have a procedure f(x, y) and we pass it i and i/2 where i is initially equal to 10. If f sets x to 42 and then evaluates y it will see the value 21 (whereas with call by reference or call by value it would still see 5). This is because the expression i/2 isn't evaluated until y is evaluated.

In many ways this appears to behave like a literal text-substitution of the parameters (with renaming to avoid name conflicts). In practice, however, this is implemented using "thunks" (basically closures) for the passed in expressions.

The Wikipedia article on Jensen's Device shows some interesting examples of using call by name. Here is one of them:

real procedure Sum(k, l, u, ak)
 значение l, u;
 целое число k, l, u;
 настоящий ак;
 комментарий k и ak передаются по имени;
 начать
 реальные с;
 s: = 0;
 для k: = l шаг 1, пока вы не сделаете
 s: = s + ak;
 Сумма: = s
 конец;

В процедуре индексная переменная k и член суммирования ak являются прошел по имени. Вызов по имени позволяет процедуре изменить значение индексной переменной во время выполнения цикла for. Звоните по имени также вызывает повторное вычисление аргумента ak во время каждой итерации петля. Обычно ak будет зависеть от изменения (побочного действия) k .

Например, код для вычисления суммы первых 100 членов действительного array V [] будет выглядеть так:

 Sum (i, 1, 100, V [i]).
16
ответ дан 27 November 2019 в 07:05
поделиться

Для тех, кто находится в будущее:

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

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


  начало целого числа i;
 целочисленная сумма процедуры (i, j);
 целое число i, j;
 параметры комментария передаются по имени;
начало целого числа см; sm: = 0;
 для i: = 1 шаг 1 до 100 сделать sm: = sm + j;
 сумма: = см
 конец;
 печать (сумма (я, я * 10))
 конец

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

3
ответ дан 27 November 2019 в 07:05
поделиться

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

 def my while (condition: => Boolean) (body: => Unit): Unit =
 if (условие) {
 тело
 mywhile (состояние) (корпус)
 }

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

 var i = 0
my while (i <10) {
 Println (я)
 я + = 1
}

Scala - это не Algol 60, но, возможно, она проливает свет.

1
ответ дан 27 November 2019 в 07:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: