lisp - 没有地方支持的推新。它被认为是破坏性的宏吗?

标签 lisp

一个函数一个宏

;; I am sorry for the confusing function name.
;; As one answer suggests, cons-if-not-member is the better name.
(defun cons-if-member (element list)
  (if (member element list)
      list
    (cons element list)))

(defmacro pushnew-no-bells (element list)
  "pushnew without place support"
  `(setq ,list (cons-if-member ,element ,list)))

(let ((xx (list 1 2)))
  (pushnew-no-bells 0 xx)
  xx)

我不知道下面哪个是正确的:

  1. cons-if-member 是一个非破坏性函数,pushnew-no-bells 是一个破坏性宏。

  2. 两者都是非破坏性的。

  3. cons-if-member 是非破坏性函数,形容词“破坏性”和“非破坏性”不适用于宏。

  4. 以上都不是

我也不知道 pushnew 是否被认为是破坏性的,但我想通过首先放弃 place 支持来简化事情。

最佳答案

pushnew 改变了它的位置形式(第二个参数)的值,所以它是破坏性的:它改变了“就地”的东西,而不是仅仅创建一个新对象(它可能与一个共享结构现有的)。您的 cons-if-member(最好称为 cons-unless-membercons-if-not-member)不会修改任何“就位”的东西,所以它实际上是非破坏性的。

请注意,顺便说一句,由于符号宏的存在,您不能真正排除“一般位置”支持。观察:

(defclass foo ()
  ((x :initform nil)))

(let ((instance (make-instance 'foo)))
  (with-slots (x) instance
    (pushnew-no-bells 1 x))
  (format t "~&Now: ~S~%" (slot-value instance 'x)))

关于lisp - 没有地方支持的推新。它被认为是破坏性的宏吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16789594/

相关文章:

lisp - 关于 Lisp 和包的新手问题

lisp - 在 Scheme 中如何比较两个字符串并忽略大小写?

lisp - 使用 cond 的简单 defun 编译器错误

class - 不同的初始化,Common Lisp

macros - lisp:何时使用函数与宏

binding - Lisp 中的哪个函数允许您比较变量名而不是它所包含的内容?

scheme - SICP (MIT-Scheme) 平方根程序

functional-programming - 我可以在 PLTScheme 中反汇编我的代码吗?

lisp - 从列表中删除元素

binary - 将分数从十进制转换为二进制