不是数字原子 LISP

Not numeric atoms LISP

我想问一下为什么这个功能不起作用...

(defun nenum(ls)
  (cond
   ((null ls) nil)
   ((listp car(ls)) (nenum (rest ls))) 
   ((numberp car(ls)) (nenum (rest ls)))
   (t (cons (car ls) (nenum (rest ls))))))

示例:(nenum '(l 1 i (b) (5) s -2 p)) --> (l i s p)

谢谢!

car(ls) 替换为 (car ls)

查看您在其中一个条件项中的谓词:

(listp car (ls))

因此应用带有两个参数 car 的函数 listp 和不带参数调用函数 ls 的结果。 carls 都需要是自由变量,listp 需要是一个不同于 defined in CLHS 的函数,因为它只需要一个参数。

也许您在编写 Algol 时遇到过这种情况? Algol 函数调用看起来像 operator(operand) 但不是 CL。 CL 是一种 LISP 方言,我们在函数调用中有这种形式:

(operand operator)

如果我们嵌套我们做同样的事情:

(operand (operand operator))

你在备选方案中做对了(cons (car ls) (nenum (rest ls)))

这里有一个更简单的方法来编写该函数:

(defun nenum (list)
   (remove-if (lambda (item)
                  (or (listp item)
                      (numberp item)))
              list))

请注意 NIL 不需要自己的测试,因为 listp 涵盖了它。

没有必要从头开始编写这样的函数。 Common Lisp已经提供了remove-if,你可以给它一个匹配数字和非原子的谓词:

CL-USER> (remove-if #'(lambda (x)
                        (or (numberp x)
                            (not (atom x))))
                    '(l 1 i (b) (5) s -2 p))
;=> (L I S P)

或者,为了更清楚地表明您保留了非数字原子,您可以使用 remove-if-not 和一个检查数字原子的谓词:

CL-USER> (remove-if-not #'(lambda (x)
                            (and (atom x)
                                 (not (numberp x))))
                        '(l 1 i (b) (5) s -2 p))
;=> (L I S P)

请注意,通常()的空列表只是符号 。因此,它也是一个非数字原子。如果您想保留其他符号,例如

CL-USER> (remove-if-not #'(lambda (x)
                            (and (atom x)
                                 (not (numberp x))))
                        '(li (b) -1 (5) sp))
;=> (LI SP)

那么您可能还想保留 nil

CL-USER> (remove-if-not #'(lambda (x)
                            (and (atom x)
                                 (not (numberp x))))
                        '(van (b) () (5) a))
;=> (VAN NIL A)