Lisp 将宏存储推入功能,但不将其移出功能
我有一个功能:Lisp 将宏存储推入功能,但不将其移出功能,lisp,common-lisp,mutability,Lisp,Common Lisp,Mutability,我有一个功能: (defun multi-push (L P) (print (if L "T" "F")) (print P) (when L (multi-push (cdr L) (push (car L) P))) P) 我试图将一个列表推到另一个列表上(我知道输入列表L是反向的。这是出于设计)。print语句是有意义的,但是当我查看变量P时,它并没有像我预期的那样发生突变 示例REPL输出: CL-USER> bob (3 3 3) CL-USER>
(defun multi-push (L P)
(print (if L "T" "F"))
(print P)
(when L
(multi-push (cdr L) (push (car L) P)))
P)
我试图将一个列表推到另一个列表上(我知道输入列表L
是反向的。这是出于设计)。print语句是有意义的,但是当我查看变量P
时,它并没有像我预期的那样发生突变
示例REPL输出:
CL-USER> bob
(3 3 3)
CL-USER> (multi-push (list 1 2) bob)
"T"
(3 3 3)
"T"
(1 3 3 3)
"F"
(2 1 3 3 3)
(1 3 3 3)
CL-USER> bob
(3 3 3)
我做错了什么?我认为,PUSH
(根据[)将其第二个参数在适当的位置进行了变异。我还尝试了一些变体,在再次调用L
和P
上的multi-PUSH
之前,我将POP
和P
需要注意的一点是,
(13)
行是多推功能的输出。这也让我感到困惑。推的破坏性变化是绑定,而不是列表。推的更正确的修改是一个“位置”,它是
一种适合用作一般参考的形式
其中“广义参考”是
对存储对象的位置的引用,就像对变量的引用一样
这两段引用自CLHS术语表:讨论这一点的部分是
特别是:
> (let* ((l1 '(1 2 3))
(l2 l1))
(push 0 l1)
(values l1 l2))
(0 1 2 3)
(1 2 3)
还请注意,这是合法的CL,因为它不会破坏性地改变引用的列表结构。push
必须是宏,因为函数不能执行它所做的操作:不能编写函数f
:
(让*((a(清单1、2、3))
(b)(a)
(f a b)
(不是(等式a b)))
那是真的
您可以将(push x y)
看作是扩展到类似(setf y(cons x y))的内容
,只是它可以正确地处理多次求值。更明确地说,PUSH是一个宏,它可以转换为代码来完成工作。它不是一个函数,不能作为函数编写。它看起来像是在试图跟踪函数在每次调用中接收到的输入。如果是这样,您可以去掉print语句和改为(跟踪多推)。调试完成后,执行(取消跟踪多推)@Xach:我现在已经澄清了:对不起,我应该在原始答案中这样说。您的multipush
是一个函数,但请注意push
是一个宏。这是有充分理由的。