2010-06-03 26 views
14

Pracuję nad zadaniem domowym, w którym jesteśmy proszeni o wdrożenie strategii oceny zwanej "call by name" w pewnym języku, który opracowaliśmy (używając Schematu).Co to jest "Call By Name"?

Otrzymaliśmy example in Scala, ale nie rozumiem, jak działa "połączenie według nazwy" i jak to się różni od "połączenia przez potrzebę"?

Odpowiedz

23

Call-by-need jest pamiętną wersją nazwy wywoławczej (patrz wikipedia).

W wywołaniu nazwa argument jest oceniany za każdym razem, gdy jest używany, podczas gdy w razie potrzeby jest oceniany przy pierwszym użyciu, a wartość rejestrowana, aby następnie potrzebować nie podlega ponownej ocenie.

+0

mam już wdrożone wezwanie potrzebie, a kiedy Robiłem to pierwsze wdrożenie bez buforowania, nie ma dla mnie sensu, że profesor prosi mnie o zrobienie czegoś, co już zrobiłem, ponieważ chcę zrozumieć prawdziwą różnicę między wezwaniem przez potrzebę a wywołaniem po imieniu – forellana

+0

Potwierdziłem to z profesorem, to jest po nazwisku, byłem zdezorientowany, ponieważ już napisaliśmy ten kod i teraz on prosi nas ponownie o to – forellana

9

Wywołanie za pomocą nazwy jest parametrem przekazującym schemat, w którym parametr jest oceniany, gdy jest używany, a nie, gdy wywoływana jest funkcja. Oto przykład pseudo-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. 
} 

Wyrażenie argument leniwie oceniano dostęp uzyskać bieżące wartości ekspresji argumentów.

+0

Ocena leniwości jest oceniana co najwyżej raz, nazwa wywołania jest oceniana zero, jeden lub więcej razy. –

+0

niekoniecznie: http://en.wikipedia.org/wiki/Lazy_evaluation –

+0

Nie wiem o Schemacie, ale w Scali (która nie ma leniwych parametrów), to rozróżnienie jest całkowicie dokładne. –

2

Dodaj to do powyższych odpowiedzi:

pracy poprzez SICP section on Streams. Daje dobre objaśnienie zarówno nazwy wywoławczej, jak i połączenia telefonicznego. Pokazuje również, jak wdrożyć te w Schemacie. BTW, jeśli szukasz szybkiego rozwiązania Oto podstawowe call-by-potrzeby realizowanego na schemacie:

;; 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)) 

Trasa próbki:

> (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' i' force' są jednak r5r? faktycznie, przynajmniej tak stary jak r3rs. –

+0

@ sgm tak, są one częścią standardu. Chciałem tylko pokazać, jak można je wdrożyć. –