Metacircular评估员,实施环境

Yur*_*rov 3 lisp scheme interpreter sicp metacircular

我正在尝试根据Harold Abelson和Gerald Jay Sussman着名的"计算机程序的结构和解释"一书中的方案实施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))
Run Code Online (Sandbox Code Playgroud)

但是,我无法理解为什么

(define myenv (setup-environment))
Run Code Online (Sandbox Code Playgroud)

应该像我们在Scheme中所期望的那样工作,因为,据我所知,Scheme默认情况下将变量按值传递给函数,因此在将"define-variable!"应用于initial-env两次之后,每次都不会更改initial-env ,并且setup-environment函数将在extend-environment返回时返回值.

我的理解错误在哪里,你能告诉我吗?

先感谢您!

Joh*_*nts 5

你的问题可能是一个teensy更具体一点,但我相信我的理解.

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

"我对这种行为感到惊讶

(define myenv (setup-environment))
(define-variable! 'a 13 myenv)
(lookup myenv 'a)
Run Code Online (Sandbox Code Playgroud)

具体来说,我希望它失败,因为Scheme是按值调用的."这是你的问题吗?

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

那么,Scheme没有任何东西可以阻止你改变或"改变"一个值.在此示例中,set-car!调用会改变它所引用的列表.然后,任何可以"看到"此值的代码都可以看到此更改.

我认为你的根本问题实际上与"价值呼唤"的含义有关,我希望我已经阐明了它.