Lisp `A';不是预期的类型“REAL';

Lisp `A';不是预期的类型“REAL';,lisp,Lisp,服务器下面的代码用于显示列表中的整数数 (defun isNum (N) (and (<= N 9) (>= N 0))) (defun count-numbers (list) (let ((count 0)) (dolist (item list count) (cond ((null list) nil) (((and (<= N 9) (>= N 0))) item)(incf count))

服务器下面的代码用于显示列表中的整数数

(defun isNum (N)
  (and (<= N 9) (>= N 0)))

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list count)
      (cond
       ((null list) nil)
       (((and (<= N 9) (>= N 0))) item)(incf count))
       (setq(0 + count))))))
(defun isNum(N)
(和(=n0)))
(取消计数编号(列表)
(让((计数0))
(项目列表计数)
(续)
((空列表)无)
((和(=N 0))项(增量计数)
(setq(0+计数(()())))
当我运行命令时,我得到的错误
A'不是预期的类型
REAL'
(count numbers'(3 4 5 6 a 7 b))

我很惊讶它居然会运行,因为您的
cond
构造不正确,您在代码的不必要的副作用生成位中切换到了中缀符号,并且在
count numbers
中使用了未绑定的变量。假设,如果它真的运行了,这个错误听起来是正确的。您正在对参数进行数值比较(以及对非数值输入的错误)

今天我戴上了codereview帽子,让我们更深入地讨论一下


Lisp(实际上,哪一个并不重要,因为这适用于CL、Scheme和所有混血儿)使用带破折号的
小写蛇形格,而不是
小写蛇形格
作为变量和函数名

(defun is-num (n)
  (and (<= n 9) (>= n 0)))

((and(=n0))
不是调用函数的方式。实际上,你需要使用它的名字,而不仅仅是试图调用它的身体。如果您试图运行此代码,就会出现许多错误,这就是其中一个错误的来源

(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
子句,它可能做不到您认为它做的事情。它实际上被视为两个独立的条款;检查
是否为
编号
,如果是,则返回。第二个函数尝试检查变量
incf
,如果它的计算结果为
t
(它没有,也不会),则返回
count
。当您在列表中找到一个数字时,您似乎想要增加计数器
count
,这意味着您应该将
incf
子句与
项一起放入

(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
    ,变量
    +
    计数作为参数
  • 您没有
    setq
    的第二部分,这意味着您试图隐式地将上面的值设置为
    NIL
  • 为了返回一个值,实际上不需要设置任何东西
在这一点上,我们终于有了一段可以正确计算和运行的代码(它不会抛出您上面提到的错误)


dolist
是一个迭代构造,它为给定列表中的每个元素执行某些操作。这意味着您实际上不需要使用该
cond
手动测试列表终止。此外,由于
dolist
不收集结果,因此没有理由将
返回给它。您还对您在
let
中声明的本地
计数进行了不必要的跟踪

(defun count-numbers (list)
  (let ((count 0))
    (dolist (item list)
      (when (numberp item) (incf count)))
    count))

像往常一样,您可以通过一个更简单的
循环
调用来完成这一切

(defun count-numbers (list)
  (loop for item in list
        when (numberp item) sum 1))
这使得计数器隐式,并使您无需手动返回计数器。事实上,除非这是编写自己的迭代函数的特别练习,否则Common Lisp有一个内置的
count if
,它接受
谓词序列[一些其他选项]
,并返回
序列中与
谓词
匹配的
项的
计数。如果您想命名
计算数字
,特别是出于风格原因,您可以

(defun count-numbers (list) (count-if #'numberp list))
就这样吧



总而言之,很好的尝试,但在提出进一步问题之前,请先尝试一下这个家族。

我很惊讶它居然会运行,因为您的
cond
构造不正确,您在代码的不必要的副作用生成位中切换到了中缀符号,并且在
计数中使用了未绑定的变量。假设,如果它真的运行了,这个错误听起来是正确的。您正在对参数进行数值比较(以及对非数值输入的错误)

今天我戴上了codereview帽子,让我们更深入地讨论一下


Lisp(实际上,哪一个并不重要,因为这适用于CL、Scheme和所有混血儿)使用带破折号的
小写蛇形格,而不是
小写蛇形格
作为变量和函数名

(defun is-num (n)
  (and (<= n 9) (>= n 0)))

((and(=n0))
不是调用函数的方式。实际上,你需要使用它的名字,而不仅仅是试图调用它的身体。如果您试图运行此代码,就会出现许多错误,这就是其中一个错误的来源

(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
子句,它可能做不到您认为它做的事情。它实际上被视为两个独立的条款;检查
是否为
编号
,如果是,则返回。第二个函数尝试检查变量
incf
,如果它的计算结果为
t
(它没有,也不会),则返回
count
。当您在列表中找到一个数字时,您似乎想要增加计数器
count
,这意味着您应该将
incf
子句与
项一起放入

(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))
是错误的,原因有三

  • 您似乎又回到了中缀符号,这意味着第二位实际上正在尝试调用函数