我正在学习 lisp,我必须从 Lisp 中的函数返回修改后的输入参数。
考虑这个简单的例子:
(defun swap (l1 l2)
(let ((temp))
(setf temp l1)
(setf l1 l2)
(setf l2 temp)))
(setf a (list 1 2 3))
(setf b (list 7 8 9))
(swap a b)
(print a)
(print b)
它不起作用,因为我不知道如何将对变量的引用传递给函数。这在lisp中甚至可能吗?这个功能怎么解决?
更新
;;; doesn't change original
(defun foo1 (x)
(setf x (list 0 0 0)))
;;; but this does
(defun foo4 (x)
(setf (car x) 0)
(setf (cdr x) (list 0 0)))
我想通过引用传递变量以便能够更改它的原因是,当我有带有 3 个输入参数的函数并且该函数应该更改所有参数时,我认为通过引用更改它们更优雅,然后返回三个变量的列表,然后用它们覆盖原始变量:
;;; more elegant function
(defun foo (x y z)
;;... some work ...
;; Lets PRETEND this does work
(setf x new-x)
(setf y new-y)
(setf z new-z))
; after this, a,b,c will have new values
(foo a b c)
;;; less elegant function
(defun foo (x y z)
;; ... some work ...
(list new-x new-y new-z))
; after this, I still will have to manually set a,b,c
(setf temp (foo a b c))
(setf a (nth 0 tmp))
(setf b (nth 1 tmp))
(setf c (nth 2 tmp))
为了解释我为什么要做到这一点,我得到了河内塔的作业。我正在考虑使用三个列表作为stacks
并在它们上使用pop
和push
函数来插入和删除“光盘”。我定义(move n source target temp)
了函数,它通过n-1
变化递归地调用自己。问题是,当我pop
或push
堆栈在递归函数中时,它不会影响外部堆栈。如果我希望我的move
函数在移动后返回堆栈n
,我真的应该返回新堆栈列表(那个不太优雅的函数)而不是通过引用编辑它们(那个更优雅的函数)
函数式语言的正确方法是什么?