clojure - 在 Clojure 的元循环评估器中评估 "true"

标签 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进行案例分析,然后决定在环境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

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

最初设置环境时,显式添加 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 表达式时,代码会失败,因为它找不到“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版本中可以正常工作(如果truefalse没有添加到中,则不起作用setup-environment,看起来 eval 没有将 true 解释为需要在 Clojure 版本的环境中查找的内容。

不幸的是,我不明白这种查找在Scheme版本中是如何发生的,以及为什么它在Clojure版本中没有发生。

我希望有人能引导我朝着正确的方向解释为什么评估 true 在方案中有效,但在元循环评估器的 Clojure 实现中不起作用。

最佳答案

我假设您正在使用 Clojure 的内置阅读器,而不是根据字符串输入自己实现它。 truefalse 不会读取为符号,而是读取为 bool 值,然后您的 variable? 函数可能不会为 bool 值返回 true。

相应地,您可以编写 (define-variable! 'true true initial-env),就好像您相信 'truetrue 是不同的值(value)观;它们是相同的,就像 '66 是相同的。

关于clojure - 在 Clojure 的元循环评估器中评估 "true",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36511466/

相关文章:

clojure - 在 Clojure 中实现二叉搜索树

scheme - 为什么STklos没有first,word,sentence,butfirst,last等功能?

scheme - SICP Ex。 1.17 - "fast-multiply"比 "multiply"慢?

algorithm - 斐波那契的 SICP 解决方案,设置 `a + b = a` ,为什么不设置 `a + b = b` ?

lisp - DrRacket 解释器是否使用基于 SICP 练习 1.5 的正常顺序评估?

exception - 如何访问 `clojure.lang.Compiler$CompilerException`实例的行变量?

binding - 使用 Clojure 在运行时动态绑定(bind)函数

clojure - Incanter 是否支持稀疏矩阵?

macros - 在Scheme中使用define-macro捕获变量的机制

Lisp 程序产生契约(Contract)违规