DrRacket不运行SICP练习1.10中的Ackermann功能

时间:2014-12-05 16:08:23

标签: scheme racket sicp mit-scheme

我最近开始阅读SICP并阅读本书中的摘录。我在命令行上安装了两个mit-scheme,稍微修补了一下,我偶然发现DrRacket并安装了来自http://www.neilvandyke.org/racket-sicp/的SICP组件

一切都运转正常,直到我来到Excercise 1.10,当我写这个函数时,它写在书中:

(define (A x y)
  (cond ((= y 0) 0)
        ((= x 0) (* 2 y))
        ((= y 1) 2)
        (else (A (- x 1)
                 (A x (- y 1))))))

然后使用cmd + R运行代码,然后当我从repl调用它时:

> (A 1 10)

我收到错误

A: undefined;
cannot reference an identifier before its definition

但是,相同的代码适用于命令行上安装的版本。这里发生了什么?在DrRacket mit-scheme实施中是否存在某些问题,或者我在这里做错了什么?

我在Mac OS X Yosemite上使用DrRacket版本6.1.1(m3)

非常感谢任何帮助,谢谢!

3 个答案:

答案 0 :(得分:2)

SICP语言尝试直接使用该语言使本书的示例工作,但是存在潜伏的错误。 R6RS之前的所有Scheme版本都不区分大小写,这意味着您可以编写此版本并使其运行正常:

(define (test a)
  (+ A a)) ; A and a are the same

(TEST 5) ; ==> 10

我相信作者的工作基于Racket中的#!r5rs语言实现,这是本书中使用的最接近版本的语言。它也像SICP一样不区分大小写。但是,对于两种语言,交互窗口似乎都有所不同。似乎它希望定义窗口中定义的每个标识符都被命名为好像它是以小写字母定义的,并且交互窗口不区分大小写。因此,如果将(TEST 5)移至交互窗口,则会出现错误:

> (TEST 5)
. . TEST: undefined;
 cannot reference an identifier before its definition

代码和交互由语言模块解析器中的不同解析器函数读取。显然他们已经使语法区分不敏感,但读取仍然区分大小写。您可以输入(read)对其进行测试,然后将其TeSt提供给它,它将打印TeSt而不是test。如果您在定义窗口中执行(define x 'TeSt)并在交互窗口中评估x,则会打印test。通过将每个标识符更改为小写,Racket使其不区分大小写。由于这是在R5RS和SICP​​中我希望SICP基于R5RS并且该bug是继承的。您可以通过两种方式解决此问题。一种是始终使用小写标识符。您将遵循惯例,当您推进案例敏感计划报告时,它不会受到伤害。另一种方法是在定义窗口的任何位置添加一行:

(#%require r5rs/init) ; fix interactions window

点击 RUN 后,交互窗口不区分大小写,因为它应该是早期的Scheme。

> (TEST 5)
10
>

快乐的黑客攻击!

答案 1 :(得分:0)

fwiw,我试着打电话给(a 1 10)并且它有效,虽然我将该功能定义为A ..我不知道为什么会这样,但我会接受任何答案详细阐述了这个问题。将此标记为其他任何有相同问题的答案。

答案 2 :(得分:0)

“定义”区域区分大小写,但“交互”区域不是