Das ist für Funktionen möglich ist, um Symbole gebunden, in der aktuellen Umgebung:
(setf (symbol-function 'myfn) #'identity)
Es gibt auch (setf FDEFINTION)
die meistens tut das gleiche, aber unterstützt auch setf
Funktionen.
Man kann es nicht für lexikalisch gebundene Funktionen tun (durch FLET
und LABELS
).
Beispiel, wie eine Symbolfunktion einstellen (setf fdefinition)
CL-USER 11 > (setf (fdefinition 'myfn) #'identity)
#<Function IDENTITY 410003F974>
CL-USER 12 > (myfn 10)
10
Weitere Ausführungen mit
Beachten Sie, dass es funktioniert, dass in der aktuellen Umgebung. So
(defun myfn (x) x)
könnte durch so etwas wie
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (fdefinition 'myfn) #'identity))
Tha Vorteil ersetzt werden: die Funktion wie gewohnt während der Kompilierung bekannt ist.
Eines der Dinge im Auge zu behalten:
Das Symbol Objekt kann einige Informationen tragen. Zum Beispiel Name des ursprüngliche Funktion, wenn gab es ein:
CL-USER 13 > #'identity
#<Function IDENTITY 410003F974>
die Funktionszelle eines Symbol einstellen, ändert sich nicht, dass:
CL-USER 14 > #'myfn
#<Function IDENTITY 410003F974>
Es ist das gleiche Funktion Objekt mit seinem ursprünglichen internen Namen.Man kann in der Lage sein, diesen Namen zugreifen zu können, aber man kann es nicht ändern:
CL-USER 18 > (nth-value 2 (function-lambda-expression #'identity))
IDENTITY
Es gibt auch ein Problem mit sich selbst rekursive Funktionen:
CL-USER 19 > (defun foo (n)
(if (zerop n)
1
(* n (foo (1- n))))) ; here foo calls the function foo
FOO
jetzt setzen wir BAR
die Funktion zu verwenden, FOO
CL-USER 20 > (setf (symbol-function 'bar) #'foo)
#<interpreted function FOO 4060004084>
CL-USER 21 > (bar 10)
3628800
Hier definieren wir FOO
:
CL-USER 22 > (defun foo (n)
(if (zerop n)
1
(+ n (foo (1- n)))))
FOO
BAR
verwendet immer noch die alte FOO
, die möglicherweise die neue FOO
aufrufen oder nicht.
CL-USER 23 > (bar 10)
460
OOPS! Wir haben FOO geändert, aber es hat seltsame Auswirkungen auf BAR: Die erste Iteration ist der alte FOO und der nächste rekursive Aufruf ist der neue FOO.
BAR
und FOO
sind zwei verschiedene Versionen der gleichen Funktion. Aber beide nennen die Funktion FOO
, die die alte oder die neue Funktion sein kann - je nachdem, wie Sie den Code interpretieren oder übersetzen.
Nur eine Idee, Sie könnten ein Makro hinzufügen, das auf 'erweitert (defun myfun (& Restargumente) (gelten Identität Args)). Natürlich könnte man in einem Lisp-1 einfach '(definiere myfn identity)'. – Cactus
Sehen Sie sich auch einige der Funktionen an, die mit dem Duplikat verknüpft sind. Es gibt viele nützliche Informationen, die herumfliegen. Die eine mit dem Titel ** warum defun ist nicht das gleiche wie (setq)? ** hat eine gute Diskussion. –
Um klar zu sein, können Sie den Funktionswert eines Symbols auch mit der Notation '# 'abrufen. Das heißt, Sie müssen nicht 'tun (((id (lambda (x) x))) (komponieren id ...))'. Sie können einfach '(lassen Sie ((ID # 'Identität)) (komponieren ID ...))' oder '(komponieren #' Identität ...)'. –