Scheme 使用Racket实现SICP评估器
我正在开发Scheme 使用Racket实现SICP评估器,scheme,racket,sicp,Scheme,Racket,Sicp,我正在开发4.1.4的元循环计算器,将计算器作为一个程序运行,使用Racket构建它: #lang racket (require (combine-in rnrs/base-6 rnrs/mutable-pairs-6)) (define (evaluate exp) (cond ; ... ((definition? exp) (display exp) (display " i
4.1.4的元循环计算器,将计算器作为一个程序运行
,使用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中输入内容的框之后,我键入(定义一个0)
,结果是:
(定义一个0)是另外一种东西
如果我删除,它可以被识别
(require (combine-in rnrs/base-6
rnrs/mutable-pairs-6))
但如果没有它,我就无法调用set car代码>或设置cdr代码>。set-
功能是否有替代方案
或者我可以选择从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)
用racket语言运行此命令将为我提供:
--> is user input
-->(define a 0)
(define a 0) is a definition
-->(list 1 2 3)
(list 1 2 3) is something else
如您所见,输入了条件的右分支
您确定错误来自else
分支吗?因为您的错误消息包含一个:
,显示在else分支中,所以不要显示
编辑:您在输入提示中输入了什么?
混淆可能是对Racket的eval
函数的调用需要一个列表作为参数,(eval'(定义一个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)
用racket语言运行此命令将为我提供:
--> is user input
-->(define a 0)
(define a 0) is a definition
-->(list 1 2 3)
(list 1 2 3) is something else
如您所见,输入了条件的右分支
您确定错误来自else
分支吗?因为您的错误消息包含一个:
,显示在else分支中,所以不要显示
编辑:您在输入提示中输入了什么?
混淆可能是对Racket的eval
函数的调用需要一个列表作为参数,(eval'(定义一个0))
。但是,如果在输入提示中输入此项,它将不起作用。您必须编写(定义一个0)
,就像普通定义一样。以下是错误:
(require (combine-in rnrs/base-6
rnrs/mutable-pairs-6))
包rnrs/base-6
和rnrs/mutable-pairs-6
带来了一些不可预测的变化cons
(以及car
,cdr
)导致(定义一个0)
未被定义捕获?
解决方案:
(require (only-in (combine-in rnrs/base-6
rnrs/mutable-pairs-6)
set-car!
set-cdr!))
始终仅将放在中的中,以避免任何不必要的绑定。以下是错误:
(require (combine-in rnrs/base-6
rnrs/mutable-pairs-6))
包rnrs/base-6
和rnrs/mutable-pairs-6
带来了一些不可预测的变化cons
(以及car
,cdr
)导致(定义一个0)
未被定义捕获?
解决方案:
(require (only-in (combine-in rnrs/base-6
rnrs/mutable-pairs-6)
set-car!
set-cdr!))
始终仅将放在中的中,以避免任何不必要的绑定。除定义外的表达式是否有效?如果是,请添加definition?
的定义,因为这一定是问题所在。您如何准确地调用eval
?我是说,你是怎么通过考试的parameters@Rahn问题不在于定义?
。我做了一个快速测试,评估了read
的结果,它成功地将表达式识别为定义。因此,问题一定是如何调用eval
。exp
参数必须与(read)
的结果不同,否则它会起作用。@ÓscarLópezeval
已添加。@HyperZeval
已添加。除定义之外的表达式是否起作用?如果是,请添加definition?
的定义,因为这一定是问题所在。您如何准确地调用eval
?我是说,你是怎么通过考试的parameters@Rahn问题不在于定义?
。我做了一个快速测试,评估了read
的结果,它成功地将表达式识别为定义。因此,问题一定是如何调用eval
。exp
参数必须与(read)
的结果不同,否则会起作用。@ÓscarLópezeval
已添加。@HyperZeval
已添加。