Common Lisp: Anfänger Probleme mit FUNCALL
-
06-07-2019 - |
Frage
Ich versuche, eine Funktion als Argument übergeben und diese Funktion innerhalb einer anderen Funktion aufrufen.
Ein Stück meines Code sieht wie folgt aus:
(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
(printboard board))
Strategie wird als Symbol in einer zweidimensionalen Liste als etwas wie ‚randomstrategy
vertretenenIch erhalte die Fehlermeldung: „FUNCALL:‚RANDOMSTRATEGY ist keine Funktion Namen, versuchen, ein Symbol anstelle ...
Wenn ich Strategie ersetzen mit ‚randomstrategy es funktioniert gut. Ich kann auch unabhängig nennen randomstrategy. Was ist das Problem?
Lösung
ist stategy eine Variable mit einem funktionellen Wert? wenn nicht als Syntax Makro ‚Verwendung # davor. das heißt # 'Strategie. oder (wenn die Funktion ist global) ‚Strategie
WARUM? weil Argumente von FUNCALL Anruf evaluted. Und Ihre Strategie Symbol ist nur ein Variablenname in diesem Fall. Variabe dieser Wert ‚RANDOMSTRATEGY. Aber Sie sollten geben, eine Funktion FUNCALL. wie Funktion zugreifen, wenn wir Symbol haben?
Drei Fälle:
1) Symbol may denote variable with functional value 2) Symbol may denote global function (symbol-function - is the accessor in this case. 3) Symbol may denote local function (flet, labels and so on)
so aussehen wie Sie vergessen RANDOMSTRATEGY Funktion
zu definieren,(defun RANDOMSTRATEGY und so weiter ...)
Hmm
FUNCALL: 'RANDOMSTRATEGY
kann sein, Sie haben (setq Strategie '' RANDOMSTRATEGY)?
dann wird Strategie zu ‚RANDOMSTRATEGY bewerten. Haben Sie bemerkt, 'vor Symbolnamen? ‚RANDOMSTRATEGY <=> (Zitat RANDOMSTRATEGY) es ist keine richtige Funktion Name
Andere Tipps
Das Problem ist, dass der Variable strategy
nicht das Symbol randomstrategy
enthält, sondern vielmehr die Liste (!) 'randomstrategy
(die eine Kurzschreibweise für (quote randomstrategy)
ist).
Nun, Sie könnte , natürlich, extrahieren Sie das Symbol aus der Liste über die Funktion second
, aber das wäre das eigentliche Problem auf nur decken, was wahrscheinlich auf die Call-Kette irgendwo ist. Versuchen Sie herauszufinden, warum das Argument, das übergeben wird getmove
funktionieren 'randomstrategy
ist, nicht randomstrategy
wie es sein sollte. (Vielleicht hat man irrtümlich ein Angebot innerhalb einer angegebenen Liste?)
Oh, und lassen Sie sich nicht durch die Tatsache verwechselt werden, dass (funcall 'randomstrategy ...)
funktioniert. Der Ausdruck 'randomstrategy
nicht, nach allem, um sich selbst zu bewerten, sondern auf das Symbol randomstrategy
Haben Sie Strategie überall eingestellt? Es sieht aus wie eine Scoping-Ausgabe.
Versuchen Sie, diese
(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))
Nicht den Code zu sehen, ich stelle mir vor, Sie so etwas wie dies tun:
(defun randomstrategy (a b c) ...)
und dann dies zu tun:
(getmove ‚randomstrategy x y z)
Was Sie tun möchten, ist die Funktion "randomstrategy" pass auf getmove # mit ':
(getmove # 'randomstrategy x y z)
In CommonLisp, #‘ergibt sich die Funktion auf das Symbol gebunden, das ist was Sie wollen passieren getmove.