【问题标题】:What’s the sequence of evaluation concerning `parameterize' and `let' in Racket?在 Racket 中,关于“参数化”和“让”的评估顺序是什么?
【发布时间】:2013-07-28 04:04:18
【问题描述】:

在关于parameterize 的球拍指南中,有以下代码:

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

(let ([get (parameterize ([location "with a fox"])
             (lambda () (location)))])
  (get))

代码返回"here"

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

【问题讨论】:

    标签: lisp scheme racket evaluation let


    【解决方案1】:

    这是许多语言(不仅仅是 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 body...
    9. 你调用(get),它会查找location的当前值,即"here",这就是结果。

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

    (define location (make-parameter "here"))
    
    (let ([get (parameterize ([location "with a fox"])
                 (let ([loc (location)])
                    (lambda () loc)))])
      (get))
    

    现在lambda 关闭loc,它应该具有预期值。

    【讨论】:

      猜你喜欢
      • 2020-06-07
      • 1970-01-01
      • 2015-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-18
      • 1970-01-01
      相关资源
      最近更新 更多