我将元循环评估程序的Structure and Interpretation of Computer Programs (SICP)版本转换为Clojure。主要区别(除了语法)是环境结构的处理。由于您无法在Clojure中使用set-car!
和set-cdr!
,因此这些是通过持有地图的原子(从Greg Sexton's chapter 4 notes on GitHub的代码复制而来)实现的。
这两个评估者的代码可以在这里找到:
主要程序eval
进行案例分析,然后在环境exp
中使用表达式env
决定下一步该做什么:
(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评估员交互时,您可以执行以下操作:
;;;评估输入:
(defn hello-string 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-expression时,代码会失败,因为它无法找到" true"。 (如果您只评估true
,在Scheme版本中评估为#t
),也会发生同样的情况。
;;;评估输入:
(如果是真正的hello-string" hi")
CompilerException java.lang.Throwable:未知的表达式类型" true" -
EVAL,编译:(/ home / erooijak / clojure / scheme-interpreter / scheme-
evaluator.clj:314:1)
(我希望将其评估为"你好")
由于eval-if
在Scheme版本中正常运行(如果true
和false
未添加到setup-environment
,则无效,看起来像eval
不会将true
解释为需要在Clojure版本的环境中查找的内容。
不幸的是,我没有看到这个查找在Scheme版本中究竟是如何发生的,以及为什么它不会在Clojure版本中发生。
我希望有人可以指导我为什么评估true
在计划中有效,而不是在元循环评估员的Clojure实现中。
答案 0 :(得分:3)
我认为你使用的是Clojure的内置阅读器,而不是基于字符串输入自己实现它。 var ranNum = 48
var numbered = 45
if (ranNum === numbered){
alert("match");
}else if ((Math.abs(numbered - ranNum)) < 10){
alert("your ten away");
}else if ((Math.abs(numbered - ranNum)) < 5){
alert("your five away");
}
和true
不是作为符号读取,而是作为布尔值读取,然后您的false
函数可能不会为布尔值返回true。
相关地,您编写variable?
,就像您认为(define-variable! 'true true initial-env)
和'true
是不同的值一样;它们是相同的,就像true
和'6
一样。