评估" true"在Clojure中的元循环评估者

时间:2016-04-09 00:45:30

标签: clojure scheme sicp evaluator

我将元循环评估程序的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)

  ;;;评估值:
  <环境地图>

  ;;;评估输入:
  你好串

  ;;;评估值:
  喂

这表明可以在环境中存储和检索新帧。

最初设置环境时,会明确添加truefalse

(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版本中正常运行(如果truefalse未添加到setup-environment,则无效,看起来像eval不会将true解释为需要在Clojure版本的环境中查找的内容。

不幸的是,我没有看到这个查找在Scheme版本中究竟是如何发生的,以及为什么它不会在Clojure版本中发生。

我希望有人可以指导我为什么评估true在计划中有效,而不是在元循环评估员的Clojure实现中。

1 个答案:

答案 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一样。