我转换了Structure and Interpretation of Computer Programs (SICP) Clojure 的元循环求值器的版本。主要区别(除了语法之外)是环境结构的处理。由于您无法在 Clojure 中使用 set-car!
和 set-cdr!
,因此它们是通过持有映射的原子(从 Greg Sexton's chapter 4 notes on GitHub 的代码复制)来实现的。
两个评估器的代码可以在这里找到:
主程序eval
进行案例分析,然后决定在环境env
中对表达式exp
下一步做什么:
(defn eval [exp env]
(cond (self-evaluating? exp) exp
(variable? exp) (lookup-variable-value exp env)
(quoted? exp) (text-of-quotation exp)
(assignment? exp) (eval-assignment exp env)
(definition? exp) (eval-definition exp env)
(if? exp) (eval-if exp env)
(lambda? exp) (make-procedure (lambda-parameters exp)
(lambda-body exp)
env)
(begin? exp) (eval-sequence (begin-actions exp) env)
(cond? exp) (eval (cond->if exp) env)
(application? exp) (apply (eval (operator exp) env)
(list-of-values (operands exp) env))
:else (throw (Throwable. (str "Unknown expression type \"" exp "\" -- EVAL")))))
与 Clojure 评估器交互时,您可以执行以下操作:
;;; Eval input:
(defn hello-string hello)
;;; Eval value:
< environment map >
;;; Eval input:
hello-string
;;; Eval value:
hello
这表明新的帧可以存储在环境中并从环境中检索。
最初设置环境时,显式添加 true
和 false
:
(defn 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))
但是当输入 if 表达式时,代码会失败,因为它找不到“true”。 (如果您只评估true
,也会发生同样的情况,在Scheme版本中评估为#t
)。
;;; Eval input:
(if true hello-string "hi")
CompilerException java.lang.Throwable: Unknown expression type "true" --
EVAL, compiling:(/home/erooijak/clojure/scheme-interpreter/scheme-
evaluator.clj:314:1)
(I would expect this to be evaluated to "hello")
由于eval-if
在Scheme版本中可以正常工作(如果true
和false
没有添加到中,则不起作用setup-environment
,看起来 eval
没有将 true
解释为需要在 Clojure 版本的环境中查找的内容。
不幸的是,我不明白这种查找在Scheme版本中是如何发生的,以及为什么它在Clojure版本中没有发生。
我希望有人能引导我朝着正确的方向解释为什么评估 true
在方案中有效,但在元循环评估器的 Clojure 实现中不起作用。
最佳答案
我假设您正在使用 Clojure 的内置阅读器,而不是根据字符串输入自己实现它。 true
和 false
不会读取为符号,而是读取为 bool 值,然后您的 variable?
函数可能不会为 bool 值返回 true。
相应地,您可以编写 (define-variable! 'true true initial-env)
,就好像您相信 'true
和 true
是不同的值(value)观;它们是相同的,就像 '6
和 6
是相同的。
关于clojure - 在 Clojure 的元循环评估器中评估 "true",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36511466/