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返回时返回值.
我的理解错误在哪里,你能告诉我吗?
先感谢您!
你的问题可能是一个teensy更具体一点,但我相信我的理解.
具体来说,您的问题似乎是这样的:
"我对这种行为感到惊讶
(define myenv (setup-environment))
(define-variable! 'a 13 myenv)
(lookup myenv 'a)
Run Code Online (Sandbox Code Playgroud)
具体来说,我希望它失败,因为Scheme是按值调用的."这是你的问题吗?
如果是这样,那么我想我可以回答它.按值调用并不意味着值不能改变.它只是意味着函数调用涉及将值从调用者传递给被调用者.实际上,几乎所有语言都是按值调用的; 这个词被广泛误解了.例如,Java也是一种按值调用的语言.
那么,Scheme没有任何东西可以阻止你改变或"改变"一个值.在此示例中,set-car!调用会改变它所引用的列表.然后,任何可以"看到"此值的代码都可以看到此更改.
我认为你的根本问题实际上与"价值呼唤"的含义有关,我希望我已经阐明了它.