gpt4 book ai didi

LISP 局部/全局变量赋值

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

如果我们定义一个像这样的函数

(defun foo(x)
(setf x somevalue))

x 定义为局部变量还是全局变量?使用 setf/q 将值设置为全局值。如果它是全局的,谁能告诉我如何在 let 之外的 lisp 中定义局部变量?

谢谢!

考虑下面的例子

(let ((x 0)) 
(defun foo (y)
(when (equal x 0) (setq x y))
(when (< x y) (setq x y))
x))

当我向 foo 提供一些输入时,例如 (foo 2) ,它返回 2,如果我们再次使用 (foo 1) 执行函数 它仍然返回 2 而 (foo 3) 返回 3。这就是我真正想要的。但问题是这怎么可能,因为如果我尝试访问变量 x 在 clisp 终端的函数之外,我无法访问。如果我再次访问该函数,它似乎保留了 x 的先前值。

谢谢!

最佳答案

为了与其他语言(如 C、C++、Java 或 Python)相提并论,您的代码更改的是“局部变量”,即使这不是 Lisper 会使用的措辞(Lisp 说法中的措辞是局部变量) “绑定(bind)”)。

您可以像您的示例一样使用函数参数或使用一些标准形式来创建局部变量,例如:

  • (让 ((x 12)) ...)
  • (做 ((x 0 (1+ i))) ...)
  • (dotimes (x 10) ...)
  • (从 0 到 10 循环 x 做 ...)

另一方面,在您的实现中,所有局部变量都可能是使用参数创建的,而其他形式只是扩展到它的宏。例如:

(let ((x 10)) ...)

相当于

(funcall (lambda (x) ...) 10)

另请注意,确实阅读您的代码片段,x 在某种意义上可能是一个“全局变量”,因为它可能已被声明为特殊的:

(defvar x 12)
;; ==> x

(defun bar ()
(format t "The value of x is ~a" x))
;; ==> bar

(defun foo (x)
(bar))
;; ==> foo

(foo 42)
The value of x is 42
;; ==> NIL

x
;; ==> 12

如果您使用 (defvar ...) 声明一个变量“特殊”,它将被不同地处理:就像每次您将它用作参数或在 中使用它一样(let ..) 形成代码将执行的操作是保存当前值,使用新提供的值,然后在退出函数或 let 后恢复该值。

所以这些变量既是“全局的”(因为外部函数可以看到它们)也是局部的(因为在你的函数或 let 终止后,以前的值将被恢复)。

标准约定是用“耳罩”命名特殊变量,即在名称的开头和结尾都有一个星号,例如:

(defvar *x* 12)

这有助于阅读您的代码的人了解变量的特殊性。请注意,这不是语言强制要求的,任何名称都可以用于特殊变量。

在 C、C++、Java 或 Python 中没有类似于特殊变量的东西。

关于 setqsetf 的最后一点说明。这里的事情有点棘手,因为您需要了解较低级别的 Lisp 才能了解为什么需要 setq。如果您使用的是 Common Lisp,那么您应该忘记 setq 并始终使用 setf

setf 是一个宏,它会在需要时扩展为 setq(不过 setq 也可以变成 setf需要时(符号宏),这是新手可能会感到困惑的地方。

你的最后一个例子是一个“闭包”的例子。当您定义一个函数(使用 (lambda ...) 形式命名或未命名)时,该函数可以“捕获”可见的变量并在以后使用它们。通常显示的一个更简单的例子是“加法器”:

(defun adder (x)
(lambda (y) (incf x y)))

此函数返回一个函数,该函数将不断将传递的值添加到内部累加器:

(let ((f (adder 10)))
(print (funcall f 3))
(print (funcall f 9))
(print (funcall f 11)))

输出将是 13 (10 + 3)、22 (13 + 9) 和 33 (22 + 11)。

匿名函数“捕获”了局部变量x,即使在退出adder 函数后也可以使用它。在 C、C++ 或 Java 等语言中,当您退出定义变量的范围时,局部变量将无法继续存在。

C++11 有未命名函数,但变量仍然无法被捕获并在作用域内存活(它们可以被复制到未命名函数的局部变量,但这不是一回事)。

关于LISP 局部/全局变量赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12333590/

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