2010-11-20 3 views
4

Der folgende Common Lisp Code erzeugt nicht den Ausgang ich es erwarten würde:Wie arbeitet das "loop for" -Makro von Common Lisp mit mehreren "und" ed-Zählern?

(loop for a from 5 to 10 
     and b = a do 
     (format t "~d ~d~%" a b)) 

Mit SCBL, erzeugt es diese Ausgabe: zu

5 5 
6 5 
7 6 
8 7 
9 8 
10 9 

Ich habe erwartet, die Werte von a und b in jeder Zeile gleich sein.

Ich habe das Web nach einer guten Dokumentation des Schleifenmakros in diesem Fall gesucht, konnte aber nicht viel finden. Ich würde mich über jede Einsicht freuen!

Antwort

11
(loop for a from 5 to 10 
     and b = a 
     do (format t "~d ~d~%" a b)) 

Above-Code kann auf eine PSETF konzeptionell Nähe zu sehen. Die Werte werden in 'parallel' aktualisiert. Der Grund ist das UND.

Lassen Sie uns für ersetzen und mit:

(loop for a from 5 to 10 
     for b = a 
     do (format t "~d ~d~%" a b)) 

Über die Variablen konzeptionell Nähe eines üblichen SETF aktualisieren, ‚nacheinander‘.

CL-USER 20 > (loop for a from 5 to 10 
        for b = a 
        do (format t "~d ~d~%" a b)) 
5 5 
6 6 
7 7 
8 8 
9 9 
10 10 

Für eine Erläuterung der Common Lisp HyperSpec 6.1.2.1 Iteration Control sehen:

Wenn mehrere Iteration Klauseln zu steuern Iteration, variable Initialisierung und Schritt auftreten sequentiell standardmäßig verwendet werden. Das und Konstrukt kann verwendet werden, um zwei oder mehrere Iterationsklauseln zu verbinden, wenn Sequentielle Bindung und Stepping nicht erforderlich sind. Die Iteration Verhalten von Klauseln verbunden durch und ist analog auf das Verhalten des Makros tun mit Bezug auf * tun.

+1

Macht jetzt Sinn, danke für die klare Erklärung! – presto8

3

Schrittformen von AND-Klauseln werden ausgewertet, bevor eine der Variablen ihre neuen Werte erhält. Verwenden Sie stattdessen for b = a then a, um die In-Order-Auswertung zu erzwingen.

Ref.-Nr. http://www.gigamonkeys.com/book/loop-for-black-belts.html#equals-then-iteration

+0

Danke für die Antwort! Ich habe versucht "für b = a dann a" und es produzierte leider die gleiche Ausgabe. – presto8

+0

@ presto8 Nun, es funktioniert für mich, ist alles was ich sagen kann. –

+0

Interessant. Ich habe versucht "a then a" auf SBCL und LispWorks und es hatte die gleichen Ergebnisse. Naja, danke trotzdem! – presto8