因此,我知道在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
  )

09-26 20:39
查看更多