关于Racket中"参数化"和"让"的评估顺序是什么?

Ben*_*Ben 3 lisp evaluation scheme let racket

在关于参数化的 "球拍指南"中,有以下代码:

(define location (make-parameter "here"))

(let ([get (parameterize ([location "with a fox"])
             (lambda () (location)))])
  (get))
Run Code Online (Sandbox Code Playgroud)

代码返回"here".

评估这段代码的顺序是什么?谢谢.

Dao*_*Wen 5

这是许多语言(不仅仅是Racket)中动态范围值的常见问题.以下是评估代码时发生的情况:

  1. location参数与值定义"here"
  2. 输入let...
  3. 输入parameterize...
  4. location使用该值动态更新参数"with a fox"
  5. 计算lambda表达式以创建一个关闭的闭包location
  6. parameterized块参数location返回还原为其原始值"here"
  7. 将所得的lambda被绑定到get
  8. 评估let身体......
  9. 你打电话(get),它会查找当前的值location,这就是"here"结果.

如果仔细阅读有关参数的文档,则说明该参数始终采用堆栈中最接近更新的值.由于您的值更新"with a fox"会在进入let正文之前从堆栈中弹出,因此当您进行实际调用时,它不再可见get.一个简单的解决方法是从参数中复制值并让闭包关闭副本:

(define location (make-parameter "here"))

(let ([get (parameterize ([location "with a fox"])
             (let ([loc (location)])
                (lambda () loc)))])
  (get))
Run Code Online (Sandbox Code Playgroud)

现在lambda结束loc,应该有预期的价值.