为什么我的Common Lisp循环只适用于简单的代码?

Alb*_*tus 3 lisp loops for-loop 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))))))))
Run Code Online (Sandbox Code Playgroud)

应该返回x的素因子列表.但是,代码只返回x.

defun评估没有错误.我试图跟踪defun中的每个函数,并且没有任何函数被评估过.循环是一个宏,所以我无法追踪它,但如果我清除循环内部并替换为

(format t "~d " i)
Run Code Online (Sandbox Code Playgroud)

它从2到x计数,就像我期望的那样.

我认为我做错了什么,但我无法理解.

Sta*_*key 6

一个问题是你(not (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))))))))
Run Code Online (Sandbox Code Playgroud)

  • (不是(mod xi))不起作用的原因是除了nil之外的任何东西在普通的lisp(包括0)中都是正确的.此外,(cons i(除数(/ xi))可能更简洁,更接近Albertus的意图. (3认同)