如何使用无名词法寻址实现闭包

时间:2015-11-02 20:43:37

标签: functional-programming scheme racket

EOPL第3章,练习3.28。它要求我构造只包含那些自由变量的闭包,而不是整个环境。但解析后,所有变量都被替换为词法地址,例如:

(lambda (x)
   (lambda (y)
     (+ x y)))

将成为:

(lambda (x)
  (lambda (y)
    (+ (var 1 0) (var 0 0))))

第一个数字是深度,第二个数字是位置。

我的问题是:

如何判断变量是否是表达式中的所有变量都无名的变量?

2 个答案:

答案 0 :(得分:2)

它们的肋骨数量大于它们在表达式中出现的深度:

(lambda (x)
  (lambda (y)
    (+ (var 1 0) (var 0 0))))

移除外部后(var 1 0)的肋骨为1,其中参考的出现深度为0,因此(var 1 0)是免费的:

(lambda (y)
    (+ (var 1 0) (var 0 0))

答案 1 :(得分:2)

保留一个计数器,表明您看到一个新闭包的次数,并且有一个环境,您可以将变量绑定到索引和深度。评估正文以便解析符号并执行(list 'var (- framcount var-frame) var-index)示例:

(lambda (x)
  ;; evironment count=0, x=(0,0)
  (lambda (y)
     ;; environment count=1, x=(0,0), y=(1,0)
     (+    ; + is a global (no match),      (glob '+)
      x    ; x is frame (- 1 0) and index 0 (var 1 0)
      y))) ; y is frame (- 1 1) and index 0 (var 0 0)

你也可以保留帧,以便解析器计算它没有找到变量的帧数以及它找到的索引。这样就不需要计数变量了。这可能是更多的方法。

  • 正如你所看到的那样,你找不到它的位置。
  • 您知道变量受到框架0 (= count row)
  • 的约束
  • 你知道它是一个大于0帧的自由变量。