Variable Bezüge in lisp
Einen anderen Neuling (Common) LISP Frage:
Grundsätzlich in den meisten Programmiersprachen gibt es ein Mittel, Funktionen zu erhalten, Referenzen auf Variablen, anstatt nur Werte, das heißt, die übergabe per Referenz statt als Wert übergeben werden. Sagen wir mal, der Einfachheit halber, ich will schreiben Sie eine LISP-Funktion, erhält eine variable und erhöht den Wert der Variablen um eins:
(defun increase-by-one (var)
(setf var (+ var 1)))
Sich jetzt natürlich das problem ist, dass diese Funktion erhöht nur den Wert der Kopie der Variablen auf dem stack, nicht die eigentlichen original-variable. Ich habe auch versucht, um den Effekt zu erzielen durch die Verwendung von Makros, ohne viel Erfolg, obwohl ich das Gefühl, dass die Verwendung von Makros ist der richtige Weg zu gehen.
Ich traf diese Wand die ganze Zeit in LISP, und ich bin sicher, es muss ein Weg, um es oder gibt es vielleicht einen völlig anderen Ansatz, um dieses problem in LISP habe ich nicht daran gedacht? Wie sind Dinge wie diese sind in LISP?
BEARBEITEN: Mehrere Leute vorgeschlagen hat, mit incf
. Ich habe nur dieses Beispiel zu demonstrieren, das problem in einer einfachen Art und Weise, war ich nicht eigentlich auf der Suche nach reimplementing incf. Aber danke für die Vorschläge sowieso.
- Sie sagen "die meisten Programmier-Sprachen", sondern es gibt Sprachen mit einer solchen Funktion anderes als C++ und Perl?
- Pascal ist ein anderes
Du musst angemeldet sein, um einen Kommentar abzugeben.
Mit lexikalischen Umfang man nicht haben Zugriff auf Variablen, die nicht im aktuellen Bereich. Sie kann auch nicht passieren lexikalische Variablen um Funktionen direkt zu. Lisp wertet Variablen und übergibt die gebundenen Werte zu dieser Variablen. Es geht nichts über erstklassige Referenzen auf Variablen.
Denke funktionsfähig!
oben gibt es zwei Funktionen. Man kann Lesen der variable, ein weiteres schreiben der variable.
Nennen wir die erste Funktion
writer
und die zweitereader
.So, zu tun, was Sie wollen, der code muss a) in den Geltungsbereich oder b) haben Sie Zugang zu Funktionen, die in den Anwendungsbereich.
Auch die variable global werden könnte,.
Dies funktioniert für Globale Variablen, die durch ein symbol repräsentiert. Es funktioniert nicht für lexikalische Variablen - diese sind nicht durch ein symbol repräsentiert.
Gibt es auch ein makro
INCF
erhöht, dass ein 'Ort' (z.B. eine variable).Aber
a
ist die variable im aktuellen scope.Die Grenze ist hier zu sehen:
Gibt es keine Möglichkeit zu passieren, einen direkten Verweis von
a
zuFOO
.Ist der einzige Weg, um eine Funktion. Wir haben auch umschreiben
FOO
, so dass es ruft die Funktion zur Verfügung gestellt.Während Common Lisp unterstützt einen funktionalen Programmierung Stil, ist nicht der Allgemeine Fokus (Schema, während die nicht rein funktional sind, ist viel näher). Common Lisp unterstützt eine vollständig Imperativ Stil Programmierung sehr gut.
Wenn Sie feststellen, Sie brauchen, um code zu schreiben wie, dass die übliche Lösung ist ein makro:
Dies ermöglicht Ihnen, code zu schreiben, wie:
wird noch erweitert werden:
bevor es kompiliert wird.
setq
stattsetf
. Diesetf
makro hat eine ganze Welt dahinter zu unterstützen verallgemeinerte Ort-Variablen, so dass die oben genanntenincrease-by-one
makro ist ungeeignet für die Verwendung mitsetf
.(setf (car foo) bar)
oder sogar(setf (fifth list) 42)
. Bei der Verwendung mit dem oben genannten makro Beispiel(fifth list)
wäre zweimal beurteilt: Siehe hier für mehr Infos: supelec.fr/docs/cltl/clm/node80.htmlNatürlich in Lisp können Sie Ihren eigenen Weg machen-variable verweisen, wenn Sie wollen. Der einfachste Ansatz ist wie folgt:
Und dann können Sie es verwenden:
Makros sind wahrscheinlich das, was Sie wollen, weil Sie nicht zu bewerten, Ihre Argumente, so dass, wenn Sie übergeben Sie eine variable-Namen, erhalten Sie einen Variablen-Namen, nicht seinen Wert.
INCF genau das tut, was Sie wollen, also, wenn Sie google "defmacro incf" finden Sie eine ganze Reihe von Definitionen für diesen, von denen einige noch nicht richtig zu schließen. 🙂
Edit: ich wurde darauf hindeutet, INCF nicht als eine alternative zum schreiben Ihren eigenen, sondern weil es das macht, was Sie wollen, und ist ein makro, so dass Sie leicht finden können-source-code für Sie, z.B., ABCL oder CMUCL.
Ich denke, Sie sind nicht auf eines der wichtigsten Konzepte der funktionalen Programmierung - Sie sollten nicht ändern Sie den Status der Objekte, sobald Sie erstellt wurden. Ändern etwas über einen Verweis gegen, die.
Wie ein Anfänger kam ich hierher, um herauszufinden, wie zu tun, was sollte eine triviale Prozedur in jeder Sprache. Die meisten Lösungen, die oben gepostet haben, nicht richtig funktionieren, wurde möglicherweise komplizierter als das, was erforderlich war, oder um unterschiedliche Implementierungen. Hier ist eine einfache Lösung für SBCL:
Anscheinend können Sie nicht verwenden
setf
b/c es schränkt den Anwendungsbereich in der Erwägung, dassset
nicht. Auch Sie verwenden müssen, umeval
vorvar
wenn man ein "argument X ist keine Zahl" - Fehler.