2016-05-03 16 views
1

Ich versuche zu verstehen, wie funktioniert das Zitat-Phänomen in Scheme. Insbesondere würde ich gerne verstehen, wann freie Variablen von zitierten Termen gebunden sind.Bindungszeit von freien Variablen der zitierten Begriffe in Schema

Zum Beispiel, wenn ich

(define q 'a) 
(define a 42) 
(eval q) 

schreiben gibt es 42. So dass ich ableiten Zeit Bindung zur Laufzeit ist. Aber in diesem Fall, warum dieser Code nicht

(let ((q 'a)) 
    (let ((a 42)) 
    (eval q) 
) 
) 

und gibt

unbound variable: a 

Kann mich jemand erklären, was das Bindungszeitmodell zitierten Begriffe ist (ist vergleichbar mit MetaOCaml zum Beispiel? (I glaube nicht so)) und der Unterschied zwischen definieren und lassen?

+1

welche Implementierung? "Tippen" wo - an der REPL, in einer Datei? –

Antwort

2

Schema hat lexikalische Disziplin, keine dynamische Disziplin.

Ihre Top-Level-Definitionen verhalten sich so, als würden Sie in einer lexikalischen Umgebung der obersten Ebene eine Bindung erstellen.

Das zweite Code-Snippet erstellt tatsächlich zwei lexikalische Umgebungen, die ineinander verschachtelt sind. Also wo (nicht "wenn") q ist gebunden, a ist immer noch ungebunden. Aber die wirkliche Frage ist, welche Umgebung von eval verwendet wird?

Ihre Implementierung verhält sich, als ob es die definitorische Umgebung verwendet oder eine Top-Level-Umgebung, aber sicher nicht die aktuelle lexikalische Umgebung, für den Symbol'a Auswertung, die den Wert des q variabel ist. Die Variableq hat eine klare bindende lexikalische Umgebung, erstellt durch seine let Form - aber wo liegt eine Symbol'a Bindung? Wie sollen wir wissen?

Details sollten in der Dokumentation sein.

1

Zunächst einmal ist ein in Anführungszeichen gesetztes Symbol genauso eine Variable wie eine Zeichenkette mit den gleichen Zeichenfolgen wie eine Variable in einer C-Syntaxsprache wie Javascript. Sie haben nichts gemeinsam, da sie in verschiedenen Welten leben.

eval kennt keine lexikalischen Variablen, nur globale. Es kennt lexikalische Variablen, die sich in der auszuwertenden Struktur befinden. Z.B.

(eval '(let ((tmp (list q q))) 
      tmp)) 

q muss global sein, aber tmp ist eine lexikalische Variable.

Standardschema, auch bekannt als R6RS, nehmen Sie ein zweites Argument, wo Sie auswählen können, welche Bibliotheken verfügbar sein sollen. Diese gelten immer noch als global.

Variablen sind zur Laufzeit gebunden. Implementierungen können beliebig optimiert und konstant gefaltet werden, solange diese Optimierung den Bericht nicht unterbricht.

eval ist ein leistungsfähiges Verfahren, das niemals verwendet werden sollte, es sei denn, es ist die sinnvollste Lösung eines Problems.Ich habe es während meiner 17-jährigen Karriere zweimal im Produktionscode gesehen, und ich denke, es ist einmal zu viel.