2015-10-30 8 views
10

Ich möchte eine spezielle Variable innerhalb einer Schleife neu binden. Dies wird normalerweise unter Verwendung eines let erreicht.Gemeinsame Lisp-Bindung im Loop-Makro

(let ((*read-eval* nil)) 
    (do-something-here)) 

Aber da die loop Makro diese schöne with Klauseln hat, dachte ich, ich könnte so dort tun können. Der Ausdruck (macroexpand '(loop with *read-eval* = nil)) endet mit der Erweiterung der Bindung auf eine let, so dass es definitiv an meiner Implementierung arbeiten wird. Aber ich kann nichts in the standard finden, was anzeigt, dass dies ein standardisiertes Verhalten ist. Also, ich denke, ist meine Frage:

(loop with *read-eval* = nil 
     for i from 1 to 10 
     do (something-involving-the-read-function)) 

Sind konforme Implementierungen erforderlich, um die bestehenden *read-eval* Variable zu ändern, oder besteht die Gefahr, dass sie eine neue lexikalische Variable mit dem gleichen Namen erstellen können?

Antwort

7

*read-eval* ist eine globale Sondervariable. Es gibt keine Möglichkeit, das rückgängig zu machen, d. H. Eine lokale lexikalische Bindung dafür zu erstellen.

with Klausel wird als mit bindings beschrieben (im Gegensatz zu bloßen Gegensatz Einstellung), was bedeutet, dass in der Tat einmal die Schleife fertig ist, werden wir wieder auf den ursprünglichen Wert (@ joshua-Schneider zu beantworten Frage).

Lassen Sie uns rational denken. (loop with foo = nil ...) stellt definitiv eine Bindung für foo her. Also, für nicht, um diese Bindung zu etablieren, muss die Implementierung überprüfen (bei Makroexpansion oder Kompilierzeit), ob *read-eval* zur Laufzeit ein dynamic variable sein wird. Das klingt wahnsinnig.

+2

Das ist wahr, aber es ist immer noch nicht klar, dass ** Schleife ** muss neu binden, im Gegensatz zu nur zuweisen. Wissen wir, dass sobald die Schleife fertig ist, wir wieder auf den ursprünglichen Wert zurückkommen werden? Ich bin mir ziemlich sicher, dass die Antwort ja lautet, basierend auf http://www.lispworks.com/documentation/HyperSpec/Body/06_abb.htm, was besagt, dass die Variablen außerhalb der Schleife nicht mehr existieren. Die Phrasierung funktioniert nicht besonders gut für spezielle Variablen, aber es sieht so aus, als ob die einzige vernünftige Interpretation eine lokale Bindung des Namens wäre, was * let * (oder * lambda * usw.) bedeuten würde. –