Compiler construction 实施方案:闭包和';设定';冲突

Compiler construction 实施方案:闭包和';设定';冲突,compiler-construction,functional-programming,scheme,closures,Compiler Construction,Functional Programming,Scheme,Closures,最近我遇到了set之间的冲突和闭包 (set!var expr)的描述如下:() set不为var建立新绑定,而是更改现有绑定的值。它首先计算expr,然后将var赋值给expr的值。在修改后的绑定范围内对var的任何后续引用都将计算为新值 关于lambda绑定的描述是:() 创建过程时,除了形式参数之外,主体内自由出现的所有变量的绑定将随过程一起保留。随后,每当该过程应用于一系列实际参数时,形式参数将绑定到实际参数,保留的绑定将被恢复,主体将被评估 我真的不明白“自由变量””是什么意思,我的闭

最近我遇到了
set之间的冲突和闭包

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

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

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

创建过程时,除了形式参数之外,主体内自由出现的所有变量的绑定将随过程一起保留。随后,每当该过程应用于一系列实际参数时,形式参数将绑定到实际参数,保留的绑定将被恢复,主体将被评估

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

  • 创建引用当前执行环境的父范围的本地范围(上下文)
  • 将快照中的所有变量存储到新创建的作用域中
  • 将所有实际参数和相应参数的名称存储在新范围中
  • 将主体作为新范围中的列表进行评估
  • 我实现
    集合的方法运算符为:()

  • 向上查找范围(沿父引用),直到包含具有给定名称的变量的范围
  • 将该范围内变量的值设置为新值
  • 这个过程在大多数情况下似乎都是有效的,但是当有
    集合时内部,旨在修改局部范围外的外部变量,这是不可能的,因为
    设置找不到真正的变量,只找到存储在闭包快照中的变量

    让我用代码解释一下:

    (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
    

    如何解决此冲突?

    简单!不要使用快照。直接访问更高级别的作用域。

    我不能直接访问它们,因为每个闭包都应该有自己的绑定。每个闭包都只有新标识符的绑定。自由变量没有新的绑定。请您解释一下“自由变量”的一般含义好吗?通过阅读wikipedia上的文章,我还没有完全理解它。@ShouYa:自由变量是一个非函数局部变量。函数中的参数和局部定义的变量不是自由变量。闭包的要点是,在函数内部,您可以从封闭范围访问变量。因此,在闭包中,既有自由(从外部捕获)变量,也有非自由(局部)变量。