2011-12-11 4 views

risposta

9

So che di solito chiediamo che il contenuto sia copiato ma non c'è una risposta breve alla tua domanda. http://www.cs.indiana.edu/~dyb/pubs/fixing-letrec.pdf

+2

The Dybvig et al. la carta è buona. C'è anche una bella [discussione su Lambda the Ultimate] (http://lambda-the-ultimate.org/node/2971) di alcuni anni fa sull'implementazione di letrec in termini di lambda. (Detto questo, sono d'accordo con il commento di sacundim che "solo perché una funzionalità è implementata con il codice imperativo dietro le quinte, ciò non rende l'imperativo della funzione"). –

8

No. Solo perché una funzionalità è implementata con codice imperativo dietro le quinte, ciò non rende la funzionalità imperativa. Le nostre macchine informatiche sono tutte indispensabili; quindi a un certo punto tutti i codici funzionali devono essere implementati mediante la traduzione in un codice imperativo!

La cosa fondamentale da capire è questo: la programmazione funzionale riguarda interfaccia, non implementazione. Un pezzo di codice è funzionale se il codice stesso non è in grado di osservare gli effetti collaterali, anche se gli effetti collaterali si verificano effettivamente dietro le quinte. Ad esempio, se si verifica il valore della stessa associazione della stessa variabile più volte, si otterrà lo stesso valore, anche se tale valore, dietro le quinte, è stato inserito da un valore di set!.

Nel caso di letrec, c'è un po 'fermo qui: il risultato è indefinito se la valutazione di una delle associazioni nel letrec provoca un altro per essere derefenced. Quindi, il risultato di questo codice è indefinito:

(letrec ((foo bar) 
     (bar 7)) 
    (cons foo bar)) 

Il valore della foo nel corpo del letrec è indefinito. Il risultato della seguente, invece, è definita:

(letrec ((foo (lambda() bar)) 
     (bar 7)) 
    (cons (foo) bar)) 

Questo perché la valutazione della lambda cattura il riferimento alla barra, ma il valore reale non viene guardato fino alla chiusura viene eseguito nel corpo.