Common Lisp:内部循环的缺点

时间:2009-11-07 10:32:13

标签: lisp common-lisp

我想知道为什么在以下代码中,d未被cons编入x。 任何提示都非常感谢。

(defun it (x) 
  (setq f '(a b c))
  (dolist (d f)
    (cons d x))
  (print x))

谢谢!

3 个答案:

答案 0 :(得分:10)

我对LISP了解不多,但我认为我知道的一些事情可能会对你有所帮助:

  • (cons d x)不将d“放入”x;它创建一个由d组成的新值,后跟x的内容。如果x是一个列表,那么(cons d x)也将是一个列表。

  • (cons d x)不更改任何内容;它会创建一个值,但是如果您没有捕获该值,它将再次被丢弃。特别是,该表达式不会改变x。

答案 1 :(得分:6)

您需要使用PUSH来破坏性地更新变量。 CONS只返回一个新的cons小区。如果你没有对那个利弊细胞做任何事情,那就消失了。也不是你需要声明所有变量。 LET引入了一个新的局部变量F,因此LET在您的示例中很有用。在未声明的变量上执行SETQ或SETF并不是一件好事 - 实际上在Lisp标准中,后果对于这样的操作是不确定的。

(defun it (x) 
  (let ((f '(a b c)))
    (dolist (d f)
      (push d x))
    (print x)))

或使用更实用的方法。

(defun it (x)
  (print (append '(a b c) x)))

你也可能想要调用REVERSE以获得不同的列表元素顺序。

答案 2 :(得分:1)

如果我理解您的意图,您希望附加包含符号 a b c f >到提供的参数x。怎么样?

 (defun it (x)
   (append (if (listp x)
               x
               (list x))
           '(a b c)))

请注意cons不会修改任何现有结构;它意味着“构造”,它创建新结构。在这种情况下,您不需要修改任何内容,除非您故意尝试编写一个 destructive函数,它将修改参数x指向的对象到位。这些函数很少见,通常以警告这种破坏性行为的方式命名,例如nconcnreverse。领先的 n 意味着“不存在”,这表明它修改了现有的结构而不是创造新的结构。