在 Clojure 的元循环求值器中求值 "true"
Evaluating "true" in meta-circular evaluator in Clojure
我转换了 Structure and Interpretation of Computer Programs (SICP) version of the meta-circular evaluator to Clojure. The main difference (besides syntax) is the handling of the environment structure. Since you cannot use set-car!
and set-cdr!
in Clojure, these are implemented via an atom holding a map (copied from the code of 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
在 Scheme 中有效,但在元循环评估器的 Clojure 实现中无效。
我假设您正在使用 Clojure 的内置 reader,而不是基于字符串输入自己实现它。 true
和 false
不读作符号,而是读作布尔值,然后您的 variable?
函数可能不 return 布尔值。
相关地,你写(define-variable! 'true true initial-env)
,好像你认为'true
和true
是不同的值;它们是相同的,就像 '6
和 6
是相同的。
我转换了 Structure and Interpretation of Computer Programs (SICP) version of the meta-circular evaluator to Clojure. The main difference (besides syntax) is the handling of the environment structure. Since you cannot use set-car!
and set-cdr!
in Clojure, these are implemented via an atom holding a map (copied from the code of 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
在 Scheme 中有效,但在元循环评估器的 Clojure 实现中无效。
我假设您正在使用 Clojure 的内置 reader,而不是基于字符串输入自己实现它。 true
和 false
不读作符号,而是读作布尔值,然后您的 variable?
函数可能不 return 布尔值。
相关地,你写(define-variable! 'true true initial-env)
,好像你认为'true
和true
是不同的值;它们是相同的,就像 '6
和 6
是相同的。