3

我正在尝试根据 Harold Abelson 和 Gerald Jay Sussman 着名的“计算机程序的结构和解释”一书在 Scheme 中实现 Metacircular Evaluator。

http://mitpress.mit.edu/sicp/full-text/sicp/book/node79.html , http://mitpress.mit.edu/sicp/full-text/sicp/book/node80.html

作者建议以这种方式设置环境:

(define (define-variable! var val env)
  (let ((frame (first-frame env)))
    (define (scan vars vals)
      (cond ((null? vars)
             (add-binding-to-frame! var val frame))
            ((eq? var (car vars))
             (set-car! vals val))
            (else (scan (cdr vars) (cdr vals)))))
    (scan (frame-variables frame)
          (frame-values frame))))

(define (setup-environment)
  (let ((initial-env
         (extend-environment (primitive-procedure-names)
                             (primitive-procedure-objects)
                             the-empty-environment)))
    (define-variable! 'true true initial-env)
    (define-variable! 'false false initial-env)
    initial-env))

但是,我不明白为什么

(define myenv (setup-environment))

应该像我们在Scheme中所期望的那样工作,因为据我所知,Scheme默认通过值传递变量来函数,因此在两次应用“define-variable!”之后 对于initial-env,initial-env不会每次都改变,setup-environment函数会返回extend-environment返回的值。

我的理解错误在哪里,请您指教?

先感谢您!

4

2 回答 2

5

你的问题可能更具体一点,但我相信我理解。

具体来说,您的问题似乎是这样的:

“我对他们的行为感到惊讶

(define myenv (setup-environment))
(define-variable! 'a 13 myenv)
(lookup myenv 'a)

具体来说,我希望它会失败,因为 Scheme 是按值调用的。”这是您的问题吗?

如果是这样,那么我想我可以回答它。按值调用并不意味着值不能改变。它只是意味着函数调用涉及将值从调用者传递给被调用者。事实上,几乎所有语言都是按值调用的。这个术语被广泛误解。例如,Java 也是一种按值调用的语言。

那么,Scheme 没有什么可以阻止您更改或“改变”一个值。在这个例子中,set-car!调用改变了它所引用的列表。然后,任何可以“看到”该值的代码都可以看到此更改。

我认为您的基本问题确实与“按价值调用”的含义有关,我希望我已经对此有所了解。

于 2012-03-16T17:59:55.893 回答
2

要了解它是如何工作的,首先您必须了解该变量initial-env将指向环境的第一帧,并且此引用永远不会被修改。环境本身是一个帧列表,每一帧都是一对列表,car第一帧的 是变量列表的头部,cdr第一帧的 是值列表的头部。

一旦清楚了,您就需要了解程序scanadd-binding-to-frame!工作方式。Scan将在当前帧的变量列表中查找与 ; 同名的变量var。如果找到,它将替换值列表中的相应值。如果未找到变量,add-binding-to-frame!将在相应列表的头部添加一个新变量和一个新值,更新框架以指向这个新头部。请注意,initial-environment它仍然指向第一帧,并且第一帧仍然指向其变量和值列表的头部(但具有新的绑定)。

所以您现在看到,即使initial-env从未更改过,它包含的列表也已就地修改,因此添加了具有各自值的新变量。我相信理解整个过程的最好方法是拿起笔和纸,一步一步地画出修改所涉及的 cons 单元的结果。

于 2012-03-16T22:32:46.593 回答