Lisp común: problemas de principiante con funcall
-
06-07-2019 - |
Pregunta
Estoy tratando de pasar una función como argumento y llamar a esa función dentro de otra función.
Una parte de mi código se ve así:
(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
(printboard board))
la estrategia se pasa como un símbolo representado en una lista bidimensional como algo como 'randomstrategy
Sigo recibiendo el error: " FUNCALL: 'RANDOMSTRATEGY no es un nombre de función; intente usar un símbolo en su lugar ...
Cuando reemplazo la estrategia con 'randomstrategy, funciona bien. También puedo llamar a randomstrategy de forma independiente. ¿Cuál es el problema?
Solución
¿es la estrategia una variable con un valor funcional? si no es así, use la macro de sintaxis # 'antes. Esa es la estrategia # '. o simplemente (si la función es global) 'estrategia
¿POR QUÉ? porque los argumentos de la llamada funcall evaluados. Y su símbolo de estrategia es solo un nombre de variable en este caso. Variabe este valor 'RANDOMSTRATEGY. Pero deberías darle a funcall una función. ¿Cómo acceder a la función si tenemos símbolo?
Tres casos:
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)
parece que olvidó definir la función RANDOMSTRATEGY
(defunde RANDOMSTRATEGY y así sucesivamente ...)
Hmm
FUNCALL: 'RANDOMSTRATEGY
puede ser que tengas (estrategia setq '' ALEATORIA ESTRATEGIA)?
entonces la estrategia evaluará a 'RANDOMSTRATEGY. ¿Notó 'antes del nombre del símbolo? 'RANDOMSTRATEGY & Lt; = & Gt; (cita RANDOMSTRATEGY) no es un nombre de función apropiado
Otros consejos
El problema es que la variable strategy
no contiene el símbolo randomstrategy
sino más bien la lista (!) 'randomstrategy
(que es una notación abreviada para (quote randomstrategy)
).
Ahora, usted podría , por supuesto, extraer el símbolo de la lista mediante la función second
, pero eso solo cubriría el problema real, que probablemente esté en algún lugar de la llamada cadena. Intente determinar por qué el argumento que se pasa a la función getmove
es (funcall 'randomstrategy ...)
, no <=> como debería ser. (¿Tal vez usó erróneamente una cita dentro de una lista citada?)
Ah, y no te dejes confundir por el hecho de que <=> funciona: la expresión <=>, después de todo, no se evalúa a sí misma, sino al símbolo <=>.
¿Has establecido una estrategia en alguna parte? Parece un problema de alcance.
Prueba esto
(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))
Sin ver el código, me imagino que estás haciendo algo como esto:
(defun randomstrategy (a b c) ...)
y luego haciendo esto:
(getmove 'randomstrategy x y z)
Lo que quieres hacer es pasar la función " randomstrategy " para moverse usando # ':
(getmove # 'randomstrategy x y z)
En CommonLisp, # 'produce la función vinculada al símbolo, que es lo que quieres pasar para moverte.