因此,我知道在Scheme中定义是用于动态作用域,而用于静态作用域,但是以下几点使我感到困惑:
如果我有
(let ((x 0))
(define f (lambda () x))
(display (f))
(let ((x 1))
(display (f))
)
)
它将显示00。到目前为止,一切都很好。但是,如果我为x添加一个额外的定义,如下所示:
(let ((x 0))
(define f (lambda () x))
(display (f))
(define x 4)
(let ((x 1))
(display (f))
)
)
它将显示undefined4。为什么是这样?为什么在评估f之后定义x 会影响(f)的返回值?为什么返回值是“未定义的”?
还值得一提的是,将f与letrec而不是define绑定(bind)也将起作用:
(let ((x 0))
(letrec ((f (lambda () x)))
(display (f))
(define x 4)
(let ((x 1))
(display (f))
)
)
)
返回00。
注意:我已经将DrRacket与在“Pretty Big”上设置的语言一起使用
最佳答案
在第二种情况下,您遇到的问题是(define x 42)
使x
成为定义它的整个作用域的变量。现在,尽管已为整个作用域定义了变量,但直到实际的(define x 42)
行,它的值才被定义。
(let ()
;; up here, `x` is defined but has an undefined value
;; ...
(define x 42)
;; down here `x` has the value 42
;; ...
)
它的行为更像是这样:
(let ([x 'undefined])
;; ... up here, `x` is 'undefined
(set! x 42)
;; ... down here, `x` is 42
)