2015-09-02 15 views
5

fand ich, dass das Programm zu überprüfen, ob die Scoping-lexikalische oder dynamisch ist derjenige unten angegeben (Quelle: http://inst.eecs.berkeley.edu/~cs61a/su10/resources/sp11-Jordy/scope/)Programm überprüfen, ob die Scoping-lexikalische oder dynamisch ist

(define test 
    (let ((scope 'lexical)) 
    (lambda() scope))) 

(let ((scope 'dynamic)) 
    (test)) 

Aber wie kann das funktionieren? Dies sollte immer lexikalisch gedruckt werden (unabhängig davon, ob der Bereich lexikalisch oder dynamisch ist) oder? Da im lokalen Bereich des Körpers der erste 'let', ist Umfang immer definiert als 'lexikalisch .. Bitte korrigieren Sie mich, wenn ich falsch bin

Antwort

6

Schema verwendet lexikalische Scoping, so dass natürlich Code immer lexical zurückgibt. In einem Lisp-System, das dynamisches Scoping verwendet, wäre scope in der Tat dynamic innerhalb dieser (let ((scope 'dynamic)) ...) Ausdruck ....

Um das zu verstehen, müssen Sie verstehen, wie dynamisches Scoping implementiert ist. Stellen Sie sich jede Variable als einen Stapel von Werten vor. Also, wenn der Lambda-Ausdruck ausgewertet wurde, wurde der Wert lexical auf scope Wert-Stack geschoben (über die let). Wenn der Baustein let verlassen wird, wird der Wert gelöscht. Später schiebt der zweite let Block den Wert dynamic auf scope 's Wertstack, was Ihre Funktion dann sieht.

Ich schätze hoch the explanation from the Emacs Lisp manual über wie dynamische Bindungen in Bezug auf einen Stapel arbeiten. Es hat mir geholfen, das Konzept wirklich zu verstehen.

+0

Ich habe die Programme in der Link und das Stack-Konzept hier erklärt. Vielen Dank für die Info. Aber wenn die Testfunktion vom zweiten 'let' aufgerufen wird, wird der Code innerhalb des define-Blocks ausgeführt und der let-Block innerhalb der Testfunktion sollte den lexikalischen Wert erneut auf den Stapel schieben, bevor der Lambda-Block ausgeführt wird, oder? .. oder was ist das Problem in meinem Verständnis der Ausführung? –

+2

@SubinP Die 'define' wird nicht ausgeführt, wenn Sie die Funktion aufrufen, die Funktion ist bereits definiert als' (lambda() scope) '. – molbdnilo

+0

Danke, es ist jetzt klar –

6

Der Wert test ist nicht

(let ((scope 'lexical)) 
    (lambda() scope)) 

es nur

(lambda() scope) 

ist, wenn Sie es nennen, (test) wird der Funktionskörper ausgewertet, und es besteht nur aus

scope 

Mit lexikalischem Umfang wäre dies der Wert in der Bindung, der in eff war wenn die Definition bewertet wurde, d. h. die lexikalisch umschließende let Bindung.

Mit dynamischem Bereich wird die Bindung von scope nicht nachgeschlagen, bis die Funktion aufgerufen wird.
Zu diesem Zeitpunkt ist die Bindung an 'lexical schon lange vorbei - es existiert nur während der Definition von test.

Wenn Sie

(let ((scope 'dynamic)) 
    (test)) 

eine neue Bindung wird in die Umwelt eingebracht, und das ist die Bindung, die gefunden wird, wenn scope aufzublicken. ist in der Tat bei der Auswertung von scope auch in einer dynamischen Umgebung wie die zu 'whatever Bindung -

Die ähnliche Funktion

(define test 
    (lambda() 
     (let ((scope 'whatever)) 
      scope))) 

so, wie Sie vorschlagen würde funktionieren - immer 'whatever zurück.

Verwandte Themen