公共Lisp中的非法函数调用

公共Lisp中的非法函数调用,lisp,common-lisp,sbcl,Lisp,Common Lisp,Sbcl,我正在制作一个两人的tic-tac-toe游戏,我正处于解决代码中所有错误的阶段。我遇到的当前错误是以下代码中的非法函数调用错误: (cond [...snip...] ((= CHOICE 3) (IF (NUMBERP (AREF *BOARD* 0 2)) (SETF (AREF *BOARD* 0 2) *MARKER*) (INVALID-SELECTION))) 我做错了什么 编辑整个函数如下所示: (defun select (choice) (

我正在制作一个两人的tic-tac-toe游戏,我正处于解决代码中所有错误的阶段。我遇到的当前错误是以下代码中的
非法函数调用
错误:

(cond

[...snip...]

((= CHOICE 3)
 (IF (NUMBERP (AREF *BOARD* 0 2))
     (SETF (AREF *BOARD* 0 2) *MARKER*)
     (INVALID-SELECTION)))
我做错了什么

编辑整个函数如下所示:

(defun select (choice)
    (cond ((= choice 1)
               (if (numberp (aref *board* 0 0)) (setf (aref *board* 0 0) *marker*)
                                                (invalid-selection))))
                ((= choice 2)
               (if (numberp (aref *board* 0 1)) (setf (aref *board* 0 1) *marker*)
                                                (invalid-selection))))
              ((= choice 3)
               (if (numberp (aref *board* 0 2)) (setf (aref *board* 0 2) *marker*)
                                                (invalid-selection))))
              ((= choice 4)
               (if (numberp (aref *board* 1 0)) (setf (aref *board* 1 0) *marker*)
                                                (invalid-selection))))
              ((= choice 5)
               (if (numberp (aref *board* 1 1)) (setf (aref *board* 1 1) *marker*)
                                                (invalid-selection))))
              ((= choice 6)
               (if (numberp (aref *board* 1 2)) (setf (aref *board* 1 2) *marker*)
                                                (invalid-selection))))
              ((= choice 7)
               (if (numberp (aref *board* 2 0)) (setf (aref *board* 2 0) *marker*)
                                                (invalid-selection))))
              ((= choice 8)
               (if (numberp (aref *board* 2 1)) (setf (aref *board* 2 1) *marker*)
                                                (invalid-selection))))
              ((= choice 9)
               (if (numberp (aref *board* 2 2)) (setf (aref *board* 2 2) *marker*)
                                                (invalid-selection))))

通常计算形式中的第一件事几乎总是一个命名函数、宏或特殊运算符的符号。表单中的第一件事是列表
(=选项3)
。更多的背景会有所帮助;正如西诺所说,这看起来像是一个无实体的条件条款


edit我将您的代码放在一个函数中,并添加了足够多的括号和变量定义来计算它,它的计算结果很好。还需要更多的上下文。

我想出来了!由于复制和粘贴技能差,函数中的括号太多。

您的函数看起来就是这样,只是因为它没有正确缩进

选择代码并缩进区域-任何理解一点Lisp的编辑器都应该为您这样做。在LispWorks中,这是通过扩展编辑器命令“缩进区域”完成的

您还可以使用更简单的情况替换COND:

(case choice
  (1 ...)
  (2 ...))
使用案例和局部函数可以使整个函数更小:

(defun select (choice)
  (flet ((do-something (x y)
           (if (numberp (aref *board* x y))
               (setf (aref *board* x y) *marker*)
             (invalid-selection))))
    (case choice
      (1 (do-something 0 0))
      (2 (do-something 0 1))
      (3 (do-something 0 2))
      (4 (do-something 1 0))
      (5 (do-something 1 1))
      (6 (do-something 1 2))
      (7 (do-something 2 0))
      (8 (do-something 2 1))
      (9 (do-something 2 2)))))

这应该会教你。切勿使用复制/粘贴。在这种情况下,您可以
(let((x(楼层选择3))(y(rem选择3))(if(numberp(aref*board*xy))(setf(aref*board*xy)*marker*)(无效选择))
,而不是长
条件。在其他情况下,将重复代码分解成函数或宏。如果您知道多个值是什么,也可以直接使用
floor
函数的两个返回值:
(多值绑定(xy)(floor choice 3)(If…)
。我的函数缩进方式与显示的不同,当我把它粘贴到页面上时,它就是这样出现的:/