为什么lisp宏推只改变符号?

gho*_*olk 1 lisp emacs macros push

在许多lisp实现中,push是一个宏看起来像这样:

(push new list)
;; equal to 
(setf list (cons new list))
Run Code Online (Sandbox Code Playgroud)

但是setf无法修改参数,例如:

(defun add-item (new list)
  (push new list))
Run Code Online (Sandbox Code Playgroud)

不起作用,因为函数参数不是原始符号.

为什么不推这样的工作:

(defun my-push (new list)
  (setcdr list (cons (car list)
                     (cdr list)))
  (setcar list new)
  list)
Run Code Online (Sandbox Code Playgroud)

然后push可以在函数的参数上工作.是否有任何理由让lisp推动这种方式?

我只是emacs lisp和sicp计划的新手.

Kaz*_*Kaz 5

破坏性push功能的一个问题是它不适用于空列表nil.这有点像"交易破坏者".

注意push宏,虽然它是一个命令式构造,它改变了保存列表头部的存储位置的值,但它避免了改变该列表的结构.

关于使用pushpop超过局部变量的列表处理代码很容易理由; 你不必担心变异列表结构可能导致的错误.