lisp - 元循环评估器,实现环境

标签 lisp scheme interpreter sicp metacircular

我正在尝试根据 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返回的值。

我哪里理解有误,请指教?

提前致谢!

最佳答案

您的问题可能很小更具体一些,但我相信我理解。

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

“我对

的行为感到惊讶
(define myenv (setup-environment))
(define-variable! 'a 13 myenv)
(lookup myenv 'a)

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

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

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

我认为您的基本问题确实与“按值调用”的含义有关,我希望我已经阐明了它。

关于lisp - 元循环评估器,实现环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9741411/

相关文章:

algorithm - 关于方案的 Dijkstra 算法

macros - 这个反引号 "syntax"在 lisp 中是如何工作的?

functional-programming - 计划作业

lisp - 比较集合的函数;有助于提高效率

printing - 执行方案代码

scala - scala解释器导致不可见文本时如何修复终端

c - 范围通常如何影响嵌套函数的使用?

java - 为我愚蠢:解析是什么?

compiler-construction - 实现编译器和解释器有什么区别?

ocaml - 用 OCaml 编写解释器