Что такое звонить по имени?

Я работаю над домашним заданием, где нас просят реализовать стратегию оценки под названием «позвонить по имени» на определенном языке, который мы разработали (используя Scheme).

Нам дали пример на Scala, но я не понимаю, как "вызов по имя» работает и чем оно отличается от «вызова по необходимости»?


person forellana    schedule 03.06.2010    source источник


Ответы (3)


Вызов по необходимости – это запомненная версия вызова по имени (см. википедию).

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

person Doug Currie    schedule 03.06.2010
comment
я уже реализовал вызов по необходимости, и когда я это делал, первая реализация была без кэширования, мне не понятно, что профессор просит меня сделать что-то, что я уже сделал, потому что я хочу понять действительно разница между звонком по необходимости и звонком по имени - person forellana; 03.06.2010
comment
я подтвердил с профессором, что это звонить по имени, я был сбит с толку, потому что мы уже пишем этот код, и теперь он снова спрашивает нас об этом - person forellana; 04.06.2010

Вызов по имени — это схема передачи параметров, в которой параметр оценивается при его использовании, а не при вызове функции. Вот пример на псевдо-C:

int i;
char array[3] = { 0, 1, 2 };

i = 0;
f(a[i]);

int f(int j)
{
    int k = j;    // k = 0
    i = 2;        // modify global i
    k = j;        // The argument expression (a[i]) is re-evaluated, giving 2.
}

Выражение аргумента лениво оценивается при доступе с использованием текущих значений выражения аргумента.

person Richard Pennington    schedule 03.06.2010
comment
Ленивая оценка оценивается не более одного раза, вызов по имени оценивается ноль, один или несколько раз. - person Randall Schulz; 03.06.2010
comment
Я не знаю о Scheme, но в Scala (у которого нет ленивых параметров) это различие совершенно точно. - person Randall Schulz; 03.06.2010
comment
эта функция должна печатать (k) в конце? Каково возвращаемое значение? - person brucebanner; 20.06.2021

Добавьте это к приведенным выше ответам:

Проработайте раздел SICP о потоках. . Это дает хорошее объяснение как вызова по имени, так и вызова по необходимости. Он также показывает, как реализовать их в Scheme. Кстати, если вы ищете быстрое решение, вот базовый вызов по необходимости, реализованный в схеме:

 ;; Returns a promise to execute a computation. (implements call-by-name)
 ;; Caches the result (memoization) of the computation on its first evaluation
 ;; and returns that value on subsequent calls. (implements call-by-need)
 (define-syntax delay
    (syntax-rules ()
      ((_ (expr ...))
       (let ((proc (lambda () (expr ...)))
             (already-evaluated #f)
             (result null))
         (lambda ()
           (if (not already-evaluated)
               (begin
                 (display "computing ...") (newline)
                 (set! result (proc))
                 (set! already-evaluated #t)))
           result)))))

 ;; Forces the evaluation of a delayed computation created by 'delay'.
 (define (my-force proc) (proc))

Пример запуска:

> (define lazy (delay (+ 3 4)))
> (force lazy) 
computing ... ;; Computes 3 + 4 and memoizes the result.
7
> (my-force lazy) 
7 ;; Returns the memoized value.
person Vijay Mathew    schedule 03.06.2010
comment
delay и force - это r5rs? на самом деле, по крайней мере, как r3rs. - person Nietzche-jou; 03.06.2010
comment
@sgm да, они являются частью стандарта. Я просто хотел показать, как их можно реализовать. - person Vijay Mathew; 03.06.2010