2012-02-18 111 views
0

我是lisp的新手,向现有列表添加元素时遇到问题。将元素添加到全局变量

> (setq l '(1 2)) 
(1 2) 
> (append l 3) 
(1 2 . 3) 
> l 
(1 2) 
> (append l '(3)) 
(1 2 3) 
> l 
(1 2) 
> (list l '(3)) 
((1 2) (3)) 
> l 
(1 2) 
> (cons 3 l) 
(3 1 2) 
> l 
(1 2) 
> (push 3 l) 
(3 1 2) 
> l 
(3 1 2) 

上面的例子是我在命令行上做的。这里只有push的作品。但是,即使push在执行我在文件中写入的代码(并将其加载到命令行中)时也不会添加该元素。我的代码示例可用in another question's page

如何更新原始l以便它自己添加3?我尝试了几个其他功能(cons,list),但结果相同/相似 - 3未添加到原始列表中。

+1

http://www.cs.cmu.edu/~dst/LispBook/ 本书解释了Common Lisp的许多基础知识。 – 2012-02-18 23:00:34

回答

2

那么你是push将一个值作为函数参数传递给一个列表?这是行不通的; push会创建一个新的cons单元格,使其指向原始列表,并将该变量设置为引用新的cons单元格。不幸的是,在中设置函数参数,该函数对最初传入的变量(函数外部)没有任何作用。

当您调用一个函数时,首先评估参数。因此,如果您将l传递给函数,实际传递的是的值l。在函数内部发生的任何事情都不会改变l所指的内容(函数外部)。

如果你想做一个类似于函数的东西,但是它实际上改变了用作参数的变量的值,你需要编写一个。或者,只需使函数返回所需的值,并在返回值返回后,将的原始变量设置为该函数的外部。事情是这样的:

(setf l (my-function l))

或者,你可以使用额外的间接水平:使l指“虚拟” cons单元,指向“真正”的名单,并更改了的cdr在你的函数中使用“虚拟”缺点。然而,这是不好的风格。通常最好使用返回值,而不是在修改的参数中“返回”数据。

请注意,如果您需要返回多个值,那并不意味着您需要修改参数; Common Lisp可以使用(values)返回函数中的多个值。