lisp - 谁能向我解释为什么这个 lisp 代码不起作用?

标签 lisp common-lisp

它应该计算列表的元素,但是说“*** - +:NIL 不是数字”

(setq A '(2 3 4 3 2 6 7 8 4 3 5 6))

(defun big (A) 
   (if (not (null (car A)))   (+ 1 (big (cdr A)))  )   ;if the first element is not null, add 1 to the count of the elements to the rest of the list
)     
 
(print (big A))

最佳答案

类型错误

IF 表达式有 2 个或 3 个参数:

(if test something)

(if test something something-else)

当它只有 2 个参数时,就好像第三个参数 something-else 是 NIL。这意味着当 test 表达式为假时,IF 表达式的计算结果为 NIL。在你的例子中,你有 2 个参数:

(defun big (A) 
  (if (not (null (car A)))
      ;; "then" branch (when condition is true)
      (+ 1 (big (cdr A)))
      ;; no "else" branch (when condition is false)
      ))

所以您知道有时调用 big 可能会返回 NIL

但是,你还写:

(+ 1 (big (cdr A)))

这个表达式看起来像 (+ 1 x),其中 x 是对 big 的调用,意味着 x 在某些情况下可能评估为 NIL。这就是您使用调试器遇到的情况。

如果您确保 if 表达式始终返回一个数字,例如在 else 分支中返回零,那么您将不会遇到与尝试将数字添加到 相同的错误>无

计数元素

但是,你仍然会有其他错误,因为你说函数 big “应该计算列表的元素”。如果你想统计一个列表的元素,你永远不需要查看列表中存储的元素,你只需要知道它们存在。

当您编写 (car a) 时,您正在访问列表的第一个元素。然后检查该值是否为非零,但是用 NIL 值填充的列表是完全有效的:

'(NIL NIL NIL)

该列表有 3 个元素,在计算它们时,它们为 NIL 的事实在任何时候都不重要。

处理列表的递归函数通常需要涵盖两种情况,即列表是否为空。您通过调用 (null list)(endp list) 检查当前列表是否为空(只需执行 (if list ... ...) 也有效,因为 NIL 是唯一的错误值)。

关于lisp - 谁能向我解释为什么这个 lisp 代码不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67864026/

相关文章:

lisp - 如何在 Lisp 的子列表中排序列表?

lisp - 方案:关于条件

tree - 查找树中最深的节点 (Lisp)

LISP 查找和替换

list - 将数字转换为英文字母列表

lisp - 是否有相当于 Common Lisp 在 Racket 中的插入?

scheme - 在 if 语句中使用 Let

lisp - 什么时候使用 defparameter 而不是 setf?

lisp - 为什么这个 defun 闭包的行为与 defparameter 闭包的行为不同?

stream - 写入后读取 *standard-input* Common Lisp