2010-06-03 40 views
14

我正在做一个家庭作业,我们被要求实施一种名为“按姓名打电话”的评估策略,并使用我们开发的某种语言(使用Scheme)。什么是“按名称呼叫”?

我们获得了example in Scala,但我不明白“名称呼叫”是如何工作的以及它与“按需呼叫”有何不同?

回答

23

按需呼叫是按名称的备忘录版本(请参阅wikipedia)。

在名称调用中,每次使用时,参数的评估值为,而在需要调用时,首次使用该参数时会进行评估,并记录该值以便随后需要不被重新评估。

+0

我已经实施的需要呼叫,而当我是这样做的第一个实现没有缓存,我不明白教授要求我做一些我已经完成的工作,因为我想了解真正的需求调用和按名称调用 – forellana 2010-06-03 14:09:34

+0

我向教授证实,这是名字叫,我很困惑,因为我们已经写了代码,现在他又问我们那 – forellana 2010-06-03 21:02:13

9

通过名称调用是一种参数传递方案,其中参数在使用时进行评估,而不是在调用该函数时评估。这是伪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. 
} 

当使用参数表达式的当前值进行访问时,参数表达式会被延迟评估。通过SICP section on Streams

工作:

+0

懒惰评估至多评估一次,按名称评估为零,一次或多次。 – 2010-06-03 03:11:50

+0

不一定是这样的:http://en.wikipedia.org/wiki/Lazy_evaluation – 2010-06-03 03:36:16

+0

我不了解Scheme,但是在Scala(没有惰性参数)中,这种区别是完全准确的。 – 2010-06-03 14:15:59

2

此添加到上述答案。它给出了名称和按需呼叫的很好解释。它还展示了如何在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. 
+0

'delay'和'force'是r5rs,但?实际上,至少和r3rs一样古老。 – 2010-06-03 06:26:11

+0

@sgm是的,它们是标准的一部分。我只是想展示他们如何实施。 – 2010-06-03 09:21:09