Общий Лисп:Проблема новичка с funcall
-
06-07-2019 - |
Вопрос
Я пытаюсь передать функцию в качестве аргумента и вызвать эту функцию внутри другой функции.
Часть моего кода выглядит так:
(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
(printboard board))
стратегия передается в виде символа, представленного в двумерном списке, например, «случайная стратегия».
Я продолжаю получать ошибку:«ФУНКОЛЛ:'RANDOMSTRATEGY не является именем функции;попробуйте вместо этого использовать символ...
Когда я заменяю стратегию на «случайную стратегию», она работает нормально.Я также могу вызвать случайную стратегию самостоятельно.В чем проблема?
Решение
является ли stategy переменной с функциональным значением?если нет, то перед ним используйте синтаксический макрос #'.это #'стратегия.или просто (если функция глобальная) 'стратегия
ПОЧЕМУ?потому что аргументы вызова funcall оцениваются.И символ вашей стратегии в данном случае — это просто имя переменной.Вариабе этого значения «СЛУЧАЙНАЯ СТРАТЕГИЯ.Но вам следует передать funcal функцию.как получить доступ к функции, если у нас есть символ?
Три случая:
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)
похоже, вы забыли определить функцию RANDOMTRATEGY
(дефан СЛУЧАЙНОЙ СТРАТЕГИИ и так далее...)
Хм
FUNCALL: 'RANDOMSTRATEGY
может быть у вас есть (стратегия setq ''RANDOMSTRATEGY)?
тогда стратегия будет оценена как «СЛУЧАЙНАЯ СТРАТЕГИЯ.Вы заметили 'перед именем символа?'RANDOMSTRATEGY <=> (цитата RANDOMSTRATEGY) это неправильное имя функции.
Другие советы
Проблема в том, что переменная Теперь вы, могли бы , конечно, извлечь символ из списка с помощью функции Да, и не позволяйте себе смущаться тем фактом, что <=> работает: выражение <=>, в конце концов, оценивает не само по себе, а символ <=>. strategy
содержит не символ randomstrategy
, а (!)
'randomstrategy
(это условное обозначение для (quote randomstrategy)
). р>
second
, но это только решило бы реальную проблему, которая, вероятно, где-то в вызове цепь. Попытайтесь определить, почему аргумент, который передается функции getmove
, является (funcall 'randomstrategy ...)
, а не <=>, как должно быть. (Может быть, вы ошибочно использовали кавычку внутри цитируемого списка?)
Вы когда-нибудь устанавливали стратегию? Похоже, проблема с ограничением объема.
Попробуйте это
(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))
Не видя код, я представляю, что вы делаете что-то вроде этого:
(defun randomstrategy (a b c) ...)
и затем делаем это:
(getmove 'randomstrategy x y z)
Что вы хотите сделать, это передать функцию " randomstrategy " чтобы сдвинуться с помощью # ':
(getmove # 'randomstrategy x y z)
В CommonLisp, # 'возвращает функцию, связанную с символом, которая что вы хотите передать getmove.