Common Lisp:是删除 - 如果与setf + remove-if相同?

h__*_*h__ 3 lisp primes common-lisp

以下代码从1到n生成素数:

(defun prime-list(n)
  (let ((a)(b)(x (floor (sqrt n))))
    (loop for i from (floor n 6) downto 1 do
          (push (1+ (* 6 i)) a)
          (push (1- (* 6 i)) a))
    (loop while (<= (car a) x) do
          (push (car a) b)
          (setf a (remove-if #'(lambda(m)(or (= 0 (mod m (car a))) (> m n))) a)))
    (append '(2 3) (reverse b) a)))
Run Code Online (Sandbox Code Playgroud)

在我看来这部分

(setf a (remove-if #'XXX a)) 
Run Code Online (Sandbox Code Playgroud)

可以替换为

(delete-if #'XXX a)
Run Code Online (Sandbox Code Playgroud)

我希望这会让它变得更快.然而,当我进行更改时,函数现在进入无限循环并且永远不会返回.为什么?

Rai*_*wig 7

如评论中所述,您需要设置变量.

DELETE-IF主要是破坏性版本REMOVE-IF.REMOVE-IF返回一个新的consed序列,它不包含已删除的元素.DELETE-IF可以返回重用的序列.

如果您有一个绑定到列表的变量,则仍需要设置结果.上面的函数返回结果,但它们不会将变量设置为结果.在列表的情况下,DELETE-IF操作的结果可以是空列表,并且副作用不可能是,可以将变量设置为它 - 当它指向非空列表时.

  • 此外,当第一个元素需要删除时返回的值将始终与原始序列不同(没有合理的方法手术删除列表的第一个缺点,同时仍然具有该缺点的poiter,所以返回第一个非 - 删除了缺点). (2认同)