插入到列表中不反映外部功能,而删除呢?

Insertion into a list doesn't reflect outside function whereas deletion does?

我是 Lisp 新手。函数删除列表中的项目会反映在函数外部,但插入不会。我怎样才能对插入做同样的事情?

例如

(defun test (a b)
  (delete 1 a)
  (delete 5 b)
  (append '(5) b)
  (member '5 b))

(setq x '(2 3 1 4))
(setq y '(8 7 5 3))

(test x y)

;;x and y after function ends
x
(2 3 4)
y
(8 7 3)

为什么追加不影响列表 y?如何从函数中向 y 中插入内容?

Append 不应该修改任何内容

Why doesn't append affect list y?

append 文档的第一句是(强调):

append returns a new list that is the concatenation of the copies.

从来没有人说过 append 应该修改列表。

您不能在其范围之外更改词法绑定的值

How can I insert something into y from within the function?

在最一般的意义上,你不能。如果 y 的值是空列表会怎样? function(与宏相反)无法在 Common Lisp 中实现这样的功能:

(let ((list '())
  (insert list 1)
  l)
;=> (1)

函数无法更改其作用域外的变量的词法绑定1,因此 insert 无法更改值列表

你当然可以修改一个对象的内部结构,所以如果list的值是一些非空列表,那么你可以修改那个对象的结构列表。 list 的值不会改变(即,它仍然是相同的 cons 单元),但由该 cons 单元表示的列表会改变。例如,

(defun prepend (list element)
  (let ((x (first list)))
    (setf (rest list) (list* x (rest list))
          (first list) element)))

(let ((list (list 1 2)))
  (prepend list 'a)
  list)
;=> (a 1 2)

保存 return 个值

一般来说,你需要养成保存函数结果的习惯。大多数函数不会修改它们的参数,因此您需要保存它们的结果。有些函数允许,但不需要修改它们的参数,而且它们不必以可预测的方式修改,所以你需要也可以保存他们的结果。例如,您的代码可以是:

(defun test (a b)
  (setf a (delete 1 a))
  (setf b (delete 5 b))
  (setf b (append '(5) b))
  (member 5 b))

(test ...)
;=> true

1 你可以通过给它一个关闭绑定等的 setter 函数来解决这个问题。但是那些技术是 解决方法.