scala 什么是“按名字呼唤”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2962987/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:11:51  来源:igfitidea点击:

What is "Call By Name"?

scalaschemelazy-evaluationevaluation

提问by forellana

I'm working on a homework assignment where we are asked to implement an evaluation strategy called "call by name" in a certain language that we developed (using Scheme).

我正在做一项家庭作业,要求我们用我们开发的某种语言(使用 Scheme)实施一种名为“按姓名呼唤”的评估策略。

We were given an example in Scala, but I don't understand how "call by name" works and how it is different to "call by need"?

我们在 Scala中获得了一个示例,但我不明白“按名称调用”的工作原理以及它与“按需要调用”有何不同?

回答by Doug Currie

Call-by-need is a memoized version of call-by-name (see wikipedia).

Call-by-need 是 call-by-name 的记忆版本(请参阅维基百科)。

In call-by-name, the argument is evaluated every time it is used, whereas in call-by-need, it is evaluated the first time it is used, and the value recorded so that subsequently it need not be re-evaluated.

在 call-by-name 中,每次使用时都会对参数进行评估,而在 call-by-need 中,在第一次使用时对其进行评估,并记录该值,以便随后无需重新评估。

回答by Richard Pennington

Call by name is a a parameter passing scheme where the parameter is evaluated when it is used, not when the function is called. Here's an example in pseudo-C:

按名称调用是一种参数传递方案,参数在使用时计算,而不是在调用函数时计算。这是伪 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.
}

The argument expression is lazily evaluated when accessed using the current values of the argument expression.

当使用参数表达式的当前值访问时,参数表达式被延迟计算。

回答by Vijay Mathew

Add this to the above answers:

将此添加到上述答案中:

Work through the SICP section on Streams. It gives a good explanation of both call-by-name and call-by-need. It also shows how to implement those in Scheme. BTW, if you are looking for a quick solution here is a basic call-by-need implemented in Scheme:

完成有关 StreamsSICP 部分。它很好地解释了按名称调用和按需求调用。它还展示了如何在 Scheme 中实现这些。顺便说一句,如果您正在寻找快速解决方案,这里是 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))

A sample run:

示例运行:

> (define lazy (delay (+ 3 4)))
> (force lazy) 
computing ... ;; Computes 3 + 4 and memoizes the result.
7
> (my-force lazy) 
7 ;; Returns the memoized value.