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ópez
eval
已添加。@HyperZ
eval
已添加。除定义之外的表达式是否起作用?如果是,请添加
definition?
的定义,因为这一定是问题所在。您如何准确地调用
eval
?我是说,你是怎么通过考试的parameters@Rahn问题不在于
定义?
。我做了一个快速测试,评估了
read
的结果,它成功地将表达式识别为定义。因此,问题一定是如何调用
eval
exp
参数必须与
(read)
的结果不同,否则会起作用。@ÓscarLópez
eval
已添加。@HyperZ
eval
已添加。