Loops 为什么我的公共Lisp循环只在普通代码上工作?

Loops 为什么我的公共Lisp循环只在普通代码上工作?,loops,for-loop,lisp,common-lisp,Loops,For Loop,Lisp,Common Lisp,我有一些代码: (defun divisor (x) (loop for i from 2 to x do (if (= x i) (return x) (if (not (mod x i)) (return (append i (divisor (/ x i)))))))) 它应该返回x的素因子列表。但是,代码只返回x defun的计算结果没有错误。我试图跟踪defun中的每个函数,但没有一个函数被计算过。循环是一个宏,

我有一些代码:

(defun divisor (x)
  (loop for i from 2 to x do
       (if (= x i) (return x) 
           (if (not (mod x i))
               (return (append i (divisor (/ x i))))))))
它应该返回x的素因子列表。但是,代码只返回x

defun的计算结果没有错误。我试图跟踪defun中的每个函数,但没有一个函数被计算过。循环是一个宏,所以我无法跟踪它,但是如果我清除循环的内部并替换为

(format t "~d " i)
它从2数到x,就像我预期的那样


我想我做错了什么,但我想不出来。

在你的循环中,我最终到达了x。然后返回x,丢弃可能从子递归返回的任何其他返回值


我认为你把循环和递归结合得不恰当。您只需要执行其中一项操作。

一个问题是,您正在使用
(而不是(mod x i))
来确定
mod
求值是否为0,这是错误的

另一个问题是,你在列表中添加原子,我不认为这正是你想要做的

以下是一个似乎有效的修订版本:

(defun divisor (x)
  (loop for i from 2 to x do
       (if (= x i) (return (list x))
           (if (= (mod x i) 0)
               (return (append (list i) (divisor (/ x i))))))))

(not(mod xi))不起作用的原因是在公共lisp(包括0)中除了nil以外的任何东西都是正确的。另外,(cons i(除数(/xi))可能更简洁,更接近阿尔伯特斯的意图。谢谢,我没有意识到0不是零。另外,append显然需要列表,而不是原子。@Daan你是对的,cons绝对是我要搜索的。谢谢!OP似乎需要素数分解(例如,12->2,2,3),而此函数返回所有不同的因子(12->2,3,4,6);完全不同。
    (defun divisor (x) 
      (loop for i from 2 to x when (eql 0 (mod x i)) collect i))