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

时间:2018-09-27 10:26:55

标签: scope racket scoping

(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)怎么样?

1 个答案:

答案 0 :(得分:0)

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

((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是什么。在动态方案中,我的重写将与普通词法方案中的重写相同,但是您的原始代码将评估(h 10) ; ==> 10,因为本地动态绑定n最接近10。