语境
- 使用像我这样的函数,
(lambda (List arg1 arg2 ... argn))
我可以使用funcall
/apply
使用原始参数调用这些方法,从而修改 lambda 中的列表。 - 对于像我这样的函数,
(lambda (arg1 arg2 ... argn &key List))
我只能将funcall
/apply
与参数的副本一起使用,这意味着我不能在函数内部修改它们。 - 如何使用 2. 中的功能与 1. 中的功能相同?
详细问题
1. 有效的功能
与(lambda (mem arg1 arg2 ... argn))
:
;; Can pass the original lists for modification inside the function:
(funcall #'fn program-memory args-list)
函数可以修改这些列表。
2. 无法修改参数的函数
使用(lambda (arg1 arg2 ... argn &key mem))
,我只能使用原始列表的副本来调用它:
;; can only pass copies of the lists :(
(apply #'fn (concatenate 'list args (list :mem program-memory)))
因此我不能再修改程序内存。
3. 如何使 2. 中的功能像 1. 中一样工作?
我怎样才能让它工作?即,使用原始列表而不是副本调用函数。
简化旧代码的示例(如 1.):
(defun mem/w (memory address value)
"Writes the value to memory at address. Returns nil."
(setf (elt memory address) value)
nil)
;; sum
(defun sum-op (mem a b o)
(mem/w mem o (+ a b)))
(let ((program (list 1 2 3 4 5 6 7 8))
(args (list 1 2 0)))
(apply #'sum-op
(cons program args))
(print program)) ;; shows modification --> good
完整代码可在https://github.com/AlbertoEAF/advent_of_code_2019/blob/master/common-lisp/day5.lisp找到。