【发布时间】:2013-02-20 10:16:10
【问题描述】:
我正在学习 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 移动后返回堆栈,我是否真的应该返回新堆栈列表(不太优雅的函数)而不是通过引用编辑它们(more优雅的功能)
函数式语言的正确方式是什么?
【问题讨论】:
-
请花几分钟时间学习how to format Lisp code。
-
函数式语言中的正确方法是什么? 在函数式语言中,您根本不做任何修改。但是,在 Common Lisp 中,您可以进行修改。
标签: lisp common-lisp