不是数字原子LISP

时间:2015-05-04 18:33:23

标签: lisp common-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)

谢谢!

4 个答案:

答案 0 :(得分:2)

查看您的一个cond术语中的谓词:

(listp car (ls))

因此,将函数listp与两个参数car一起应用,并调用函数ls而不使用参数。 carls都需要是自由变量,而listp需要与defined in CLHS不同,因为它只需要一个参数。

也许你有写作Algol? Algol函数调用看起来像operator(operand)但不是CL。 CL是一种LISP方言,我们在函数调用中有这个形式:

(operand operator)

如果我们筑巢,我们也会这样做:

(operand (operand operator))

你在替代(cons (car ls) (nenum (rest ls)))

中做得对

答案 1 :(得分:1)

car(ls)替换为(car ls)

答案 2 :(得分:1)

Here's a much easier way to write that function:

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

Note that NIL doesn't need its own test because listp covers it.

答案 3 :(得分:1)

没有必要从头开始编写这样的函数。 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)

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

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)