【问题标题】:Implement SICP evaluator using Racket使用 Racket 实现 SICP 评估器
【发布时间】:2015-12-13 07:47:09
【问题描述】:

我正在开发 4.1.4 Running the Evaluator as a Program 的元循环评估器,使用 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-6rnrs/mutable-pairs-6 导入什么吗?

【问题讨论】:

  • 定义以外的表达式是否有效?如果是这样,请添加definition? 的定义,因为它一定是问题所在。
  • 你是怎么打电话给eval的?我的意思是,你是如何传递参数的
  • @Rahn 问题不在于definition?。我做了一个快速测试,评估了read 的结果,它成功地将表达式识别为定义。因此,问题一定是您如何调用evalexp 参数必须与(read) 的结果不同,否则它会起作用。
  • @ÓscarLópez eval 已添加。
  • @HyperZ eval 已添加。

标签: scheme racket sicp


【解决方案1】:

它应该运行良好。我用你提供的代码做了一个快速测试。

(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 分支吗?因为你的错误信息包含:,所以else分支中的display不要。

编辑:您在输入提示中究竟输入了什么? 混淆可能是对 Racket 的 eval 函数的调用需要一个列表作为参数,(eval '(define a 0))。但是,如果您在输入提示中输入它,它将不起作用。你必须写(define a 0),就像一个正常的定义。

【讨论】:

    【解决方案2】:

    这是错误:

    (require (combine-in rnrs/base-6
                         rnrs/mutable-pairs-6))
    

    rnrs/base-6rnrs/mutable-pairs-6带来了一些意想不到的变化cons(以及carcdr)领先的(define a 0)未被definition?捕获

    解决方案:

    (require (only-in (combine-in rnrs/base-6
                                  rnrs/mutable-pairs-6)
                      set-car!
                      set-cdr!))
    

    始终将only-in 放入require 以避免任何不必要的绑定。

    【讨论】:

      猜你喜欢
      • 2016-03-23
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      相关资源
      最近更新 更多