为什么 (define (h n) (f 0)) 在调用 (h 10) 时求值为 100?

Why (define (h n) (f 0)) evaluate to 100 when calling (h 10)?

(define n 100)
(define (f a) n)
(define (g n) n)
(define (h n) (f 0))

为什么 (define (h n) (f 0)) 在调用 (h 10) 时计算结果为 100 而不是 10?

调用(h 10)时,n会重新定义为10还是100? (g 10)怎么样?

因此,当您创建一个过程并引入一个绑定时,它只能在该绑定的范围内访问:

((lambda (w) (+ w 10)) 2) ; ==> 12
w ; ERROR: Undefined variable (it only exists inside the lambda)

您可以重命名任何参数,只要您重命名它的所有用途即可。例如。这是完全一样的:

((lambda (w2) (+ w2 10)) 2) ; w renamed to w2 and has not effect on the outcome.

实际上,许多编译器重命名所有标识符,以便它们是唯一的。我现在将使用您的代码执行此操作:

(define n_1 100)
(define (f_1 a_1) n_1)
(define (g_1 n_2) n_2)
(define (h_1 n_3) (f_1 0))
(h_1 10) ; ==> 100

这与您问题中的代码相同。我所做的只是重命名,这样绑定就不会被使用相同名称的新闭包遮蔽。

你现在明白为什么 (h_1 10) 的计算结果为 100 了吗?

有趣的事实:在没有闭包的 lisp 语言中,我们有动态绑定。在运行时最后创建的变量决定了 n 是什么。在动态 Scheme 中,我的重写与在普通词法 Scheme 中的工作方式相同,但您的原始代码将计算 (h 10) ; ==> 10,因为本地动态绑定 n 到 10 是最接近的。