我很惊讶它的运行,因为你cond
的构造不正确,你在代码的不必要的副作用生成位中切换到中缀表示法,并且你在count-numbers
. 假设,如果它确实运行,该错误听起来是正确的。您正在对参数进行数字比较(以及非数字输入上的错误)。
我今天戴上了 codereview 帽子,所以让我们更深入地了解一下。
Lisp(实际上并不重要,afaik 这适用于 CL、Scheme 和所有杂种)使用lower-case-snake-case-with-dashes
,而不是lowerCamelCase
用于变量和函数名称。
(defun is-num (n)
(and (<= n 9) (>= n 0)))
常见的 Lisp 约定是以 结束谓词,p
而不-p
是以 . 开头is-
。Scheme具有(IMO更好)结束谓词的约定,?
而不是
(defun num-p (n)
(and (<= n 9) (>= n 0)))
((and (<= N 9) (>= N 0)))
不是你调用函数的方式。您实际上需要使用它的名称,而不仅仅是尝试调用它的主体。如果您尝试运行此代码,这是您会遇到的许多错误之一。
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((num-p item) item)(incf count))
(setq(0 + count))))))
numberp
已经存在,并对其输入进行类型检查,而不是尝试进行数字比较。您可能应该改用它。
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((numberp item) item)(incf count))
(setq(0 + count))))))
((numberp item) item) (incf count))
可能不会像您认为它作为cond
子句那样做。它实际上被视为两个单独的子句;检查是否item
是 a number
,如果是则返回。第二个尝试检查变量incf
并返回count
它是否评估为t
(它没有,也不会)。您似乎想要的是count
当您在列表中找到一个数字时增加计数器,这意味着您应该将该incf
子句与item
.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
(setq (0 + count)))))
(setq (0 + count))
是错误的事情有三个原因
- 您似乎回到了中缀符号,这意味着第二位实际上是在尝试
0
使用变量+
和count
作为参数调用函数。
- 您没有第二部分
setq
,这意味着您正在尝试将上述内容设置为NIL
隐式。
- 您实际上不需要设置任何内容即可返回值
至此,我们终于有了一段可以正确评估和运行的代码(并且它不会抛出您上面提到的错误)。
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
count)))
dolist
是一个迭代构造,它为给定列表中的每个元素做一些事情。这意味着您实际上不需要使用 that 手动测试列表终止cond
。此外,因为dolist
不收集结果,所以没有理由返回item
它。您还不必要地隐藏了count
您在let
.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list)
(when (numberp item) (incf count)))
count))
像往常一样,您可以通过更简单的loop
调用来完成所有这些操作。
(defun count-numbers (list)
(loop for item in list
when (numberp item) sum 1))
这使计数器隐含并避免您需要手动返回它。事实上,除非这是专门编写您自己的迭代函数的练习,否则 Common Lisp 有一个内置的count-if
,它接受predicate sequence [some other options]
并返回匹配count
项中的。如果你想具体命名,出于文体原因,你可以sequence
predicate
count-numbers
(defun count-numbers (list) (count-if #'numberp list))
并完成它。
总之,很好的尝试,但在提出进一步的问题之前,请尝试阅读语言家族的知识。