gpt4 book ai didi

lisp - 什么时候使用 defparameter 而不是 setf?

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:47 25 4
gpt4 key购买 nike

我目前正在阅读 Land of LISP 这本书,我刚刚读完第一章。里面写了一个让电脑猜1到100之间数字的小程序,代码如下:

(defparameter *small* 1)
(defparameter *big* 100)

(defun guess-my-number ()
(ash (+ *small* *big*) -1))

(defun smaller ()
(setf *big* (1- (guess-my-number)))
(guess-my-number))

(defun bigger ()
(setf *small* (1+ (guess-my-number)))
(guess-my-number))

(defun start-over ()
(defparameter *small* 1)
(defparameter *big* 100)
(guess-my-number))

到目前为止,我明白发生了什么,并且Using 'ash' in LISP to perform a binary search?在这方面帮助了我很多。尽管如此,还有一件事让我感到困惑:据我所知,您使用 setf 为变量赋值,并使用 defparameter 初始定义变量。我也理解了 defparameterdefvar 之间的区别(至少我相信我理解 ;-))。

所以现在我的问题是:如果我应该使用 setf 为初始化后的变量赋值,为什么 start-over 函数使用 defparameter 而不是 setf?这是有什么特别的原因,还是草率?

最佳答案

函数就是:

(defun start-over ()
(setf *small* 1)
(setf *big* 100)
(guess-my-number))

它已经被声明为一个特殊的全局变量。无需在函数内部反复执行。

可以在函数内部使用DEFPARAMETER,但这是一种糟糕的风格。

DEFPARAMETER 用于声明全局特殊变量和它们的可选文档。一次。如果您需要多次执行此操作,则主要是在重新加载整个文件或系统时完成。文件编译器还将其在顶级位置识别为动态绑定(bind)变量的特殊声明。

例子:

文件 1:

(defparameter *foo* 10)

(defun foo ()
(let ((*foo* ...))
...))

文件 2:

(defun foo-start ()
(defparameter *foo* 10))

(defun foo ()
(let ((*foo* ...))
...))

如果 Lisp 使用 compile-file 编译文件 1,编译器会识别 defparameter 并且在下面的 let 中我们有一个动态绑定(bind).

如果 Lisp 使用 compile-file 编译文件 2,编译器无法识别 defparameter 并且在下面的 let 中我们有词汇绑定(bind)。如果我们再次编译它,从这个状态,我们有一个动态绑定(bind)。

所以这里版本1更好,因为它更容易控制和理解。

在您的示例中,DEFPARAMETER 出现了多次,这没有用。我可能会问,变量在哪里定义,答案会指向多个源位置...

因此:请确保您的程序元素的大部分定义一次 - 除非您有充分的理由不这样做。

关于lisp - 什么时候使用 defparameter 而不是 setf?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23808038/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com