defparameter值不会自动更改

时间:2020-09-28 21:56:54

标签: common-lisp

在我编写的程序中,我有一些参数,例如:

(defparameter foo 3)

然后在我的代码中,我有另一个参数,该参数的值取决于上一个参数:

(defparameter bar (+ 2 foo)) 

在此示例中评估代码时,我得到的foo等于3,而bar等于5。

由于我是Common Lisp的新手,并且是编程的新手,所以我期望通过更新foo的值(例如,通过执行(setf foo 6)),我的bar值也会自动更新到8。

但事实并非如此。如果我将foo的值更新为6,尽管bar的定义为(+ 2 foo),如果我调用bar,我仍然得到其初始评估值为5。

我如何使变量在每次依赖它们的另一个变量被修改时立即更新?

2 个答案:

答案 0 :(得分:3)

由于我是Common Lisp的新手,并且是编程的新手,所以我期望通过更新foo的值(例如,通过执行(setf foo 6)),我的bar值也会自动更新到8。

期望系统能够做的事很好,但是通常您没有这种行为,即。数据流编程,以基本语言自动实现(电子表格就是其中的一个著名例子)。在您所描述的简单情况下,行为是明确定义的,但是随着程序趋于大型化,您希望控制表达式被求值时,否则您可能无缘无故地触发了许多计算,或产生比您想要的更多的副作用。

按需计算事物的构建块是函数,在您的情况下,您可以将foobar定义为函数:

(defun foo () 
  3)

(defun bar () 
  (+ 2 (foo)))

除非您努力使这些函数内联,否则更改foo的定义将影响bar计算出的值,这就是您想要的行为。

答案 1 :(得分:2)

Common Lisp遇到(defparameter *name* expression)时,将确保*name*作为特殊变量存在,然后计算表达式并将绑定设置为结果。例如。无论您更新多少foo,它都将不再能够影响bar

如果您希望动态计算某些内容,则可以创建一个函数并在每次需要该值时应用它:

(defparameter *foo* 3)
(defun bar ()
  (+ 2 *foo*))
(bar) ; ==> 5
(setf *foo* 6)
(bar) ; ==> 8