我正在研究4.1.4 Running the Evaluator as a Program
的metacircular评估员,用Racket构建它:
#lang racket
(require (combine-in rnrs/base-6
rnrs/mutable-pairs-6))
(define (evaluate exp)
(cond
; ...
((definition? exp) (display exp)
(display " is a definition\n"))
; ...
(else (display exp)
(display " is something else\n"))))
(define (definition? exp)
(tagged-list? exp 'define))
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
false))
(define (driver-loop)
(let ((input (read)))
(let ((output (evaluate input)))
output))
(driver-loop))
(driver-loop)
获得一个成功读取DrRacket输入的框后,我输入(define a 0)
,结果显示:
(define a 0) is something else
如果我删除
,我们可以认出来(require (combine-in rnrs/base-6
rnrs/mutable-pairs-6))
但如果没有,我将无法拨打set-car!
或set-cdr!
。是否有set-
函数的替代方法?
或者我可以从rnrs/base-6
和rnrs/mutable-pairs-6
选择要导入的内容吗?
答案 0 :(得分:0)
应该运行正常。我用你给的代码做了快速测试。
(define (evaluate exp)
(cond
; ...
((definition? exp) (display exp)
(display " is a definition\n"))
; ...
(else (display exp)
(display " is something else\n"))))
(define (definition? exp)
(tagged-list? exp 'define))
(define (tagged-list? exp tag)
(if (pair? exp)
(eq? (car exp) tag)
false))
(define (driver-loop)
(let ((input (read)))
(let ((output (evaluate input)))
output))
(driver-loop))
(driver-loop)
用球拍语言运行会给我:
--> is user input
-->(define a 0)
(define a 0) is a definition
-->(list 1 2 3)
(list 1 2 3) is something else
正如您所见,输入了条件的右分支。
您确定错误来自else
分支吗?由于您的错误消息包含:
,因此在其他分支中不包含display
。
编辑:您在输入提示中输入了什么?
混淆可能是对Racket的eval
函数的调用需要一个列表作为参数(eval '(define a 0))
。但是,如果您在输入提示中输入此内容,它将无法正常工作。您必须像正常定义一样编写(define a 0)
。
答案 1 :(得分:0)
这是错误:
(require (combine-in rnrs/base-6
rnrs/mutable-pairs-6))
包rnrs/base-6
和rnrs/mutable-pairs-6
带来了一些不可预测的变化,cons
(以及car
,cdr
)领导(define a 0)
未被改变被definition?
解决方案:
(require (only-in (combine-in rnrs/base-6
rnrs/mutable-pairs-6)
set-car!
set-cdr!))
始终将only-in
放入require
以避免任何不受欢迎的绑定。