2010-09-10 8 views
7

Penso di capire perché esiste un pericolo nel consentire chiusure in una lingua che utilizza l'ambito dinamico. Cioè, sembra che tu possa chiudere la variabile OK, ma quando provi a leggerlo otterrai solo il valore nella parte superiore dello stack globale. Questo potrebbe essere pericoloso se altre funzioni utilizzano lo stesso nome nel frattempo.Chiusure e ambito dinamico?

Ho perso qualche altra sottigliezza?

risposta

6

Sì, questo è il problema di base. Il termine "chiusura" è l'abbreviazione di "chiusura lessicale", tuttavia, che è by definition captures its lexical scope. Chiamerei le cose in un linguaggio con ambito dinamico qualcos'altro, come LAMBDA. Lambdas è perfettamente sicuro in un linguaggio con uno scope dinamico, purché tu non provi a restituirli.

(Per un esperimento pensiero interessante, confronta il problema di restituire un lambda ambito dinamicamente in Emacs Lisp al problema di restituire un riferimento a una variabile stack allocato in C, e come entrambi sono impossibili nello Schema.)

Molto tempo fa, quando le lingue con ambito dinamico erano molto meno rare di oggi, questo era noto come funargs problem. Il problema che hai menzionato è il problema del funargs verso l'alto.

+3

Non modificherò la risposta ma: "Solitamente" è sbagliato - le chiusure sono sempre "chiusura lessicale", chiamate così perché chiudono l'espressione sopra il suo ambiente lessicale. Per quanto riguarda il fatto che lambdas sia sicuro - non essere in grado di usare lambdas come chiusure sta diminuendo enormemente il loro valore, ma anche senza questo, l'ambito dinamico è intrinsecamente dannoso per la salute del tuo programma poiché non puoi essere sicuro del significato di qualsiasi legame. –

+0

Grazie per il collegamento funargs. Non l'ho mai saputo prima. –

+0

@Eli Barzilay: hai ragione, ero eccessivamente sdolcinato. Rimuoverò 'di solito'. Per quanto riguarda la salute del programma generale, sono completamente d'accordo, ma la domanda non è generale. Come ho detto, i lambda con uno scope dinamico sono sicuri quanto i puntatori senza restrizioni ... –

7

Mi rendo conto che sono in ritardo di anni per rispondere a questa domanda, ma mi sono imbattuto in questa domanda mentre eseguivo una ricerca sul Web e volevo correggere alcune informazioni errate pubblicate qui.

"Chiusura" indica semplicemente un oggetto chiamabile che contiene sia codice che un ambiente che fornisce collegamenti per variabili libere all'interno di quel codice. Quell'ambiente è solitamente un ambiente lessicale, ma non esiste una ragione tecnica per cui non può essere un ambiente dinamico.

Il trucco è chiudere il codice sull'ambiente e non sui valori particolari. Questo è ciò che Lisp 1.5 ha fatto, e anche ciò che MACLisp ha fatto per "down-down funargs".

si può vedere come Lisp 1.5 ha fatto questo leggendo il Lisp 1.5 manuale in http://www.softwarepreservation.org/projects/LISP/book

Prestare particolare attenzione in Appendice B a come eval gestisce FUNZIONE e come applicare le maniglie FUNARG.

È possibile ottenere il sapore di base della programmazione utilizzando chiusure dinamiche da http://c2.com/cgi/wiki?DynamicClosure

È possibile ottenere una nell'introduzione profondità alle questioni di attuazione da ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdf

moderna con scope dinamico lingue usano generalmente poco profondo legame, dove la corrente il valore di ciascuna variabile viene mantenuto in una posizione globale e le chiamate di funzione salvano i vecchi valori in pila. Un modo per implementare chiusure dinamiche con rilegatura bassa è descritto in http://www.pipeline.com/~hbaker1/ShallowBinding.html

+0

Mi rendo conto che potrei essere in ritardo a chiedere questo: P, ma ti dispiacerebbe spiegare quali sono 'make-adder',' addx' e 'do-test' form [link] (http: //wiki.c2.com/?DynamicClosure) a cui hai fatto riferimento? Detto dal manuale Lisp 1.5, non si tratta di chiusure di funzioni benché definite con 'lambda'. Sembrano più come macro e sono sostituiti con semplici espressioni (cioè senza ambienti associati). – wlnirvana

+0

Sono solo normali funzioni con ambito dinamico. Quando vengono chiamati, hanno accesso alle variabili all'interno del loro ambito dinamico. L'unica chiusura/funarg in questo programma è quella creata da FUNCTION. – Glomek

+0

Va bene, forse questa è solo una questione di nomenclatura, ma preferisco dire che non esiste una cosa chiamata "chiusure dinamiche" (che personalmente ritengo sia fonte di confusione che di chiarimento). La carta AIM-199.pdf referenziata in realtà dà l'origine della parola chiusura, il che suggerisce che è stato inizialmente utilizzato solo per espressioni lambda "chiuse". Le funzioni con ambito dinamico, le cui variabili libere escono dall'ambiente di runtime corrente, non sono chiuse in questo senso, quindi definite "espressioni lambda aperte" in quel documento. – wlnirvana