problemas de principiante com funcall: Common Lisp
-
06-07-2019 - |
Pergunta
Eu estou tentando passar uma função como um argumento e chamar essa função dentro de outra função.
Um pedaço de minha aparência código como este:
(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
(printboard board))
A estratégia é passado como um símbolo representado em uma lista bidimensional como algo como 'randomstrategy
Eu continuo recebendo o erro: "Funcall: 'RANDOMSTRATEGY não é um nome de função; tente usar um símbolo em vez ...
Quando eu substituir estratégia com 'randomstrategy ele funciona bem. Eu também pode chamar randomstrategy independente. Qual é o problema?
Solução
é stategy uma variável com um valor funcional? se não do que o uso # sintaxe' macro antes. que é a estratégia de '#. ou apenas (se a função é global) 'estratégia
POR QUE? porque os argumentos de chamada funcall Avaliamos as. E seu símbolo estratégia é apenas um nome de variável neste caso. Variabe este valor 'RANDOMSTRATEGY. Mas você deve dar a funcall uma função. como função de acesso se tivermos símbolo?
casos Três:
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 você esqueceu de definir a função RANDOMSTRATEGY
(defun RANDOMSTRATEGY e assim por diante ...)
Hmm
FUNCALL: 'RANDOMSTRATEGY
pode ser que você tem (estratégia setq '' RANDOMSTRATEGY)?
, em seguida, a estratégia será avaliada como 'RANDOMSTRATEGY. Você notou "antes do nome símbolo? 'RANDOMSTRATEGY <=> (citação RANDOMSTRATEGY) não é um nome de função adequada
Outras dicas
O problema é que a variável strategy
não contém o símbolo randomstrategy
mas sim o lista ??em> (!) 'randomstrategy
(que é uma notação abreviada para (quote randomstrategy)
).
Agora, você pode , é claro, extrair o símbolo da lista por meio do second
função, mas que só iria cobrir o verdadeiro problema, o que é, provavelmente, em algum lugar na cadeia de chamada. Tentar determinar por que o argumento que é passado para a função getmove
é 'randomstrategy
, não randomstrategy
como deveria ser. (Talvez você erroneamente usou uma citação dentro de uma lista citada?)
Ah, e não se deixe confundir pelo fato de que (funcall 'randomstrategy ...)
funciona:. A 'randomstrategy
expressão não, afinal de contas, avaliar a si mesmo, mas para o símbolo randomstrategy
Você definir qualquer estratégia? Parece uma questão de escopo.
Tente este
(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))
Não vendo o código, eu estou imaginando que você está fazendo algo parecido com isto:
(defun randomstrategy (a b c) ...)
e, em seguida, fazer isso:
(getmove 'randomstrategy x y z)
O que você quer fazer é passar a função "randomstrategy" para getmove usando # ':
(getmove # 'randomstrategy x y z)
Em CommonLisp, #' produz a função ligada ao símbolo, que é o que você deseja passar para getmove.