实现方案:闭包和'设置'!冲突

时间:2013-02-05 20:57:31

标签: compiler-construction functional-programming scheme closures

最近,我在实现方案解释器时遇到了set!和闭包之间的冲突。

(set! var expr )的描述如下:(tspl

  

set!不会为 var 建立新绑定,而是会更改现有绑定的值。它首先评估 expr ,然后将 var 分配给 expr 的值。在更改的绑定范围内对 var 的任何后续引用都将计算为新值。

关于lambda绑定的描述是:(tspl

  

创建过程时,将在过程中保留在正文中自由发生的所有变量的绑定,不包括形式参数。随后,只要将过程应用于一系列实际参数,就会将形式参数绑定到实际参数,恢复保留的绑定,并评估正文。

我真的不明白它是什么意思'自由变量',我的闭包实现是创建所有当前可用变量的快照并将快照存储到闭包中。每当执行闭包时,它将按顺序执行以下操作:(code

  1. 创建引用当前正在执行的环境的父范围的本地范围(上下文)。
  2. 将快照中的所有变量存储到新创建的范围中。
  3. 将所有实际参数与新范围中相应参数的名称一起存储。
  4. 将身体评估为新范围中的列表。
  5. 我实现set!运算符的方法是:(code

    1. 向上查找范围(沿父引用),直到包含具有给定名称的变量的范围。
    2. 将该范围内变量的值设置为新值。
    3. 这个过程似乎在大多数情况下都有效,但是如果内部有一个set!用于修改外部变量,那么由于set!无法真正找到REAL,因此无法实现变量,但只是存储在闭包快照中的变量。

      让我在代码中解释一下:

      (define x 3)
      
      ((lambda ()      ;; binding(snapshot) == { x: 3 }
         (set! x 4)    ;; changing the value in local scope which derived from the snapshot.
         (display x))) ;; ==> 4
      
      (display x)      ;; ==> 3
      

      我该如何解决这个冲突?

1 个答案:

答案 0 :(得分:3)

轻松!不要使用快照。直接访问更高级别的范围。