2010-06-03 22 views
14

Sto lavorando a un compito a casa in cui ci viene chiesto di implementare una strategia di valutazione chiamata "call by name" in una determinata lingua che abbiamo sviluppato (usando Scheme).Che cos'è "Call By Name"?

Ci è stato dato un example in Scala, ma non capisco come funziona "call by name" e in che modo è diverso da "call by need"?

risposta

23

Call-by-need è una versione memoized di call-by-name (vedere wikipedia).

In chiamata per nome, l'argomento è valutata ogni volta che viene utilizzato, mentre nel call-by-necessità, viene valutata la prima volta che viene utilizzato, e il valore registrato in modo che successivamente hanno bisogno non essere rivalutato.

+0

ho già implementato chiamata dal bisogno, e quando lo stavo facendo la prima implementazione era senza cache, non ho senso per me che il professore mi chieda di fare qualcosa che ho già fatto, perché voglio capire la vera differenza tra call by need e call by name – forellana

+0

ho confermato con il professore, che è chiamato per nome, ero confuso perché già scriviamo quel codice e ora ci sta chiedendo di nuovo per quello – forellana

9

La chiamata per nome è uno schema di passaggio dei parametri in cui il parametro viene valutato quando viene utilizzato, non quando viene chiamata la funzione. Ecco un esempio in 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. 
} 

L'espressione argomento è pigramente valutata quando si accede utilizzando i valori correnti dell'espressione tesi.

+0

La valutazione lenta viene valutata al massimo una volta, la chiamata per nome viene valutata zero, una o più volte. –

+0

non necessariamente: http://en.wikipedia.org/wiki/Lazy_evaluation –

+0

Non so su Scheme, ma in Scala (che non ha parametri pigri), questa distinzione è del tutto accurata. –

2

Aggiungere questo le risposte di cui sopra:

lavoro attraverso la SICP section on Streams. Fornisce una buona spiegazione sia di call-by-name che di call-by-need. Mostra anche come implementare quelli in Scheme. A proposito, se siete alla ricerca di una soluzione rapida: ecco un call-by-need attuato in regime di base:

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

Un esempio di esecuzione:

> (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' e' force' sono r5rs, però? in realtà, almeno vecchio come r3rs. –

+0

@sgm sì, fanno parte dello standard. Volevo solo mostrare come possono essere implementati. –

Problemi correlati