如何修复“绑定表格不正确的列表”错误

时间:2019-12-07 17:24:34

标签: lisp common-lisp

我是Lisp的新手,我试图定义一个简单函数来搜索列表中的元素。 我对语言的正当性感到不满意,也不太了解错误/警告消息。

(defun in-list (x l)
  (let y (car l))
  (let z (cdr l))
  (if (null l)
      nil
    (if (equal x y)
        t
      (in-list x z)
      )
    )
)

我也尝试用seq代替let,但仍然对“假定特殊的变量”发出警告。

2 个答案:

答案 0 :(得分:2)

let的语法有误。 correct form是:

(let ((var1 exp1)
      (var2 exp2)
      ...
      (varn expn))
  body-of-let)

所以您应该写:

(defun in-list (x l)
  (let ((y (car l))
        (z (cdr l)))
    (if (null l)
        nil
        (if (equal x y)
            t
            (in-list x z)))))

请注意,由于相应的表达式仅使用一次,因此不必定义两个局部变量,因此您可以通过以下方式缩写该函数:

(defun in-list (x l)
  (if (null l)
      nil
      (if (equal x (car l))
          t
          (in-list x (cdr l)))))

,并且由于主体中存在三种不同的情况,因此可以使用单个cond而不是两个if

(defun in-list (x l)
  (cond ((null l) nil)
        ((equal x (car l)) t)
        (t (in-list x (cdr l)))))

网络上有很多很好的免费书籍,可以学习该语言的基础。例如参见this one

答案 1 :(得分:0)

要使用setq,可以在函数的lambda列表中的&aux关键字之后声明函数的内部变量:

(defun in-list (x l &aux y z) 
    (setq y (car l) 
          z (cdr l)) 
    (and l 
         (or (equal x y) 
             (in-list x z))))

一种更好的样式是在声明时为辅助变量赋予其值:

(defun in-list (x l &aux (y (car l)) (z (cdr l)))
    (and l 
         (or (equal x y) 
             (in-list x z))))