gpt4 book ai didi

lisp - Common Lisp 中的动态绑定(bind)

转载 作者:行者123 更新时间:2023-12-04 22:34:17 24 4
gpt4 key购买 nike

这个问题是Common Lisp scoping (dynamic vs lexical)的延伸

我已经阅读并(希望)理解 Common Lisp 中范围和范围的概念(链接:https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node43.html),但我无法理解以下三个示例。所有示例都在 SBCL/Slime/Emacs 中的新 lisp session 上运行。

示例 1:打印 5 和 5

(defvar x 100)
(defun fun1 (x)
(print x)
(fun2))

(defun fun2 ()
(print x))

(fun1 5)

示例 2:打印 5 和 100

 (defun fun1 (x)
(print x)
(fun2))

(defun fun2 ()
(print x))

(defvar x 100)

(fun1 5)

示例 3:打印 5 & 5 & 100

(defvar x 100)

(defun fun1 (x)
(print x)
(fun2))

(defun fun2 ()
(print x))

(defvar x 100)

(fun1 5)

x

我理解为什么 fun1 总是打印 5(由于词法范围,但如果我错了请更正)。我不明白的是,为什么 fun2 在示例 1 中打印 5,在示例 2 中打印 100,在示例 3 中再次打印 5?

  • 示例 1:x 是一个具有不确定范围的变量,在 fun1 中设置为 5,因此 fun2 访问该值。这是正确的解释吗?
  • 示例 2:x 被 defvar 设置为 100,但为什么在调用 fun1 时没有重新设置为 5?我认为绑定(bind)是在调用函数时发生的,还是在定义函数时发生的?似乎在定义 fun1 时 x 尚未绑定(bind),因此程序的其余部分看不到 fun1 中 x 的绑定(bind)(在词法范围内),然后“全局”绑定(bind)发生在随后的 defvar。那么函数调用中的行为 x 是由于 fun1 中的词法阴影而导致 fun2 没有动态阴影吗? IE。这里有两个不同的 x 实例,因为 fun1 首先定义了它的 x 并且当时没有看到“全局”x。
  • 示例 3:这里似乎是因为 x 是首先全局设置的,所以 fun1 和 fun2 都引用了 x 的同一个实例,因此它的值在 fun1 期间更新并在 fun2 期间也应用(均为 5)?此外,当我最后询问 x 的值时,我得到 100(为什么?当 fun2 返回 5 时?)

它与 Guy Steel 的 Common Lisp 书中的以下摘录有关,但我无法理解它:

"Constructs that use lexical scope effectively generate a new name foreach established entity on each execution. Therefore dynamic shadowingcannot occur (though lexical shadowing may). This is of particularimportance when dynamic extent is involved."

以下陈述是否始终为真(来源:https://courses.engr.illinois.edu/cs421/sp2010/lectures/dynamicscope.pdf):

The binding rule in Lisp is this: a use of a name is bound to the mostrecent declaration of that name that is still live.

我开始了解其中的一些部分,但无法全面了解所有三个部分,所以如果您能提供帮助,那将非常有帮助。

最佳答案

代码的一些注释:

示例 1

(defvar x 100)    ; declares X to be special, globally and locally
; also sets X to 100

(defun fun1 (x) ; X is a dynamically bound variable
(print x) ; lookup of dynamic binding of X
(fun2))

(defun fun2 ()
(print x)) ; lookup of dynamic binding of X

(fun1 5)

示例 2

 (defun fun1 (x)  ; X is a lexical local variable
(print x) ; lexical reference to X
(fun2))

(defun fun2 ()
(print x)) ; X is undeclared/undefined
; the exact behaviour is undefined in Common Lisp
; many implementations assume dynamic lookup of X
; most compilers will show a warning
; CMUCL also by default declared X globally to be special
; -> don't use this in your code

(defvar x 100) ; declares X to be special, globally and locally
; also sets X to 100
(fun1 5)

示例 3

(defvar x 100)    ; declares X to be special, globally and locally
; also sets X to 100

(defun fun1 (x) ; X is a dynamically bound variable
(print x) ; lookup of dynamic binding of X
(fun2))

(defun fun2 ()
(print x)) ; lookup of dynamic binding of X

(defvar x 100) ; does nothing
; -> X is already declared special
; -> X already has a value
; see also: DEFPARAMETER

(fun1 5)

x ; lookup of global (or thread local) value of X

关于lisp - Common Lisp 中的动态绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64418124/

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