Common Lisp:初学者遇到funcall的问题

时间:2009-10-26 18:40:03

标签: lisp common-lisp

我正在尝试将函数作为参数传递,并在另一个函数中调用该函数。

我的代码看起来像这样:

(defun getmove(strategy player board printflag)
(setq move (funcall strategy player board))
(if printflag
    (printboard board))

策略作为二维列表中表示的符号传递为诸如'randomstrategy

之类的东西

我一直收到错误: “FUNCALL:'RANDOMSTRATEGY不是函数名;请尝试使用符号...

当我用'randomstrategy替换策略时,它运行正常。 我也可以独立调用randomstrategy。 有什么问题?

4 个答案:

答案 0 :(得分:4)

问题是变量strategy不包含符号randomstrategy,而是列表(!)'randomstrategy(这是一种简写符号(quote randomstrategy))。

现在,你可以,当然,通过函数second从列表中提取符号,但这只会覆盖真正的问题,这可能是某个地方呼叫链。尝试确定传递给函数getmove的参数为'randomstrategy而不是randomstrategy的原因。 (也许你错误地在引用列表中使用了引用?)

哦,不要因为(funcall 'randomstrategy ...)的作用而让自己感到困惑:表达式'randomstrategy毕竟不会对自身进行评估,而是对符号randomstrategy进行评估

答案 1 :(得分:2)

是一个具有功能值的变量吗?如果不是在它之前使用#'语法宏。这就是#'策略。或者只是(如果功能是全球性的)'策略

为什么?因为funcall调用的参数已经过评估。在这种情况下,您的策略符号只是一个变量名称。 Variabe这个值'RANDOMSTRATEGY。但你应该给funcall一个函数。如果我们有符号,如何访问功能?

三种情况:

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)

看起来你忘了定义RANDOMSTRATEGY函数

(defun RANDOMSTRATEGY等等......)

FUNCALL: 'RANDOMSTRATEGY

可能你有(setq策略''RANDOMSTRATEGY)?

然后策略将评估为'RANDOMSTRATEGY。 您是否注意到'符号名称前? 'RANDOMSTRATEGY< => (引用RANDOMSTRATEGY)它不是一个合适的函数名称

答案 2 :(得分:1)

你有策略在任何地方吗?这看起来像是一个范围问题。

试试这个

(setq strategy 'randomstrategy)
(setq move (funcall strategy player board))

答案 3 :(得分:0)

没有看到代码,我想你正在做这样的事情:

(defun randomstrategy(a b c)...)

然后这样做:

(getmove'randomstrategy x y z)

你想要做的是将函数“randomstrategy”传递给getmove使用#':

(getmove#'randomstrategy x y z)

在CommonLisp中,#'产生绑定到符号的函数,即 你要传递给getmove。