apply & funcall – die unterschiedlichen Ergebnisse
-
21-12-2019 - |
Frage
ANSI Common Lisp.Warum bekomme ich im letzten Fall eine andere Antwort?
(list 1 2 3 nil) ; (1 2 3 nil)
(funcall (function list) 1 2 3 nil) ; (1 2 3 nil)
(apply (function list) '(1 2 3 nil)) ; (1 2 3 nil)
(apply (function list) 1 2 3 nil) ; (1 2 3)
Lösung
APPLY
erwartet als Argumente:
- eine Funktion
- null ...n Argumente
- und am Ende eine Liste mit Argumenten
Die Funktion wird grundsätzlich mit dem Ergebnis aufgerufen (list* 0-arg ... n-arg argument-list)
Beachten Sie, dass (list* '(1 2 3))
ergibt gerade (1 2 3)
.
Die Argumente werden aufgerufen Verbreitungsfähige Argumentliste in Common Lisp.
CL-USER 60 > (apply (function list) 1 2 3 nil)
(1 2 3)
CL-USER 61 > (apply (function list) (list* 1 2 3 nil))
(1 2 3)
CL-USER 62 > (apply (function list) (list* '(1 2 3)))
(1 2 3)
APPLY
verwendet absichtlich eine solche verteilbare Argumentliste.Zum Beispiel (... 1 2 3 '(4 5))
.Mit FUNCALL
Sie müssen die Argumente wie gewohnt schreiben: (... 1 2 3 4 5)
.
APPLY
hat in Common Lisp einen einzigen Zweck:Es ermöglicht den Aufruf von Funktionen mit berechneten Argumentlisten.Um das etwas praktischer zu machen, wurde die Idee der verteilbaren Argumentliste verwendet.Es funktioniert zum Beispiel genauso in Emacs Lisp.
Stellen Sie sich vor, Sie haben eine Liste mit Argumenten und möchten zwei Argumente voranstellen.
CL-USER 64 > (apply '+ args)
60
CL-USER 65 > (apply '+ 1 2 args)
63
CL-USER 66 > (apply '+ (append (list 1 2) args))
63