34

我正在尝试使用 SICP,我得到了一些代码。所以我开始:

#lang scheme
(word 'comp 'uter)

返回错误:函数(字)未定义。

即使我试图将其复制到 IDE(运行)中:

(define word?
  (let ((number? number?)
        (symbol? symbol?)
        (string? string?))
    (lambda (x)
      (or (symbol? x) (number? x) (string? x)))))

还是一样。

我认为这可能是语言版本或其他方面的某些问题。


以上来自“简单方案”,当我在 SICP 中准确介绍代码时:

(define (sqrt x)
    (sqrt-iter 1.0 x))

IDE 返回sqrt-iter未定义。代码见第一章: http: //mitpress.mit.edu/sicp/code/index.html

4

3 回答 3

57

DrRacket中有一个SICP 兼容语言

1. 从包管理器

文档中有一个关于如何从 DrRacket 安装它的简单指南:

  1. 打开包管理器:在 DrRacket 中选择菜单“文件”,然后选择“包管理器...”。

  2. 在“Do What I mean”选项卡中,找到文本字段并输入:“sicp”

  3. 单击“安装”按钮。这会产生大量输出。即使有警告也不要担心。

  4. 测试一下。确保 DrRacket 在左下角有“Determine language from source”。编写以下程序并单击RUN

    #lang sicp 
    
    (inc 42) 
    ; ==> 43
    

这是一个使用图片语言的更高级的测试,它需要包含在#%require

#lang sicp
(#%require sicp-pict)

;; paint-hires / paint-hi-res renamed to just paint
(paint (below (beside diagonal-shading
                      (rotate90 diagonal-shading))
              (beside (rotate270 diagonal-shading)
                      (rotate180 diagonal-shading))))

单击RUN,您应该会在交互窗口中看到一个朝向中心变亮的正方形。

2 命令行安装

或者,您也可以通过运行以下命令从终端/shell 执行步骤 1-3:

raco pkg install sicp

从这里您可以执行第一个安装说明中的第 4 步来测试它。

3. 旧版本或 DrRacket 使用行星如果raco pkg不起作用

在 DrRacket 中还有一个旧版本的 SICP 兼容语言。在“从源代码确定语言”处具有左下角选择框时,您可以添加:

#lang planet neil/sicp

作为定义(顶部文本区域)中的唯一行,然后按RUN,它将被安装。重新启动 DrRacket,您会发现它在语言下拉列表中可用。祝你好运。您可能会收到很多红色的错误消息。只需忽略它并重新启动 DrRacket。您可能不再在语言菜单中找到该选项,但是通过使用#lang planet neil/sicp它启动每个文件仍然可以作为模块语言使用。

从错误来看,似乎与图片语言模块有关。我测试了这个片段,它仍然有效:

(paint-hires  (below (beside diagonal-shading
                             (rotate90 diagonal-shading))
                     (beside (rotate270 diagonal-shading)
                             (rotate180 diagonal-shading))))
于 2013-10-24T09:14:41.570 回答
18

Sylwester 的回答正是我想要的。但是,我注意到 Racket 6.5增加了对 SICP 的直接支持。我想人们可能想知道这一点。

添加 SICP 支持后,现在可以在 Racket 中编写如下代码:

#lang sicp
(#%require sicp-pict)
(paint einstein)
于 2016-05-04T06:02:50.243 回答
4

[美好的开始;继续前进,您将享受 Scheme!]

在 Scheme 中,程序是在一个环境中开发的。环境定义了从标识符到值的映射。有些值是函数,有些是数字等。定义函数时:

(define (sqrt x)
  (sqrt-iter 1.0 x))

标识符x作为参数绑定到sqrt,值 1.0 是一个数字,标识符sqrt-iter来自环境。

要问自己的一个问题是“在哪里sqrt-iter定义;它与什么有关?” 由于它不是由您定义的,sqrt-iter因此必须来自内置到您的方案中的环境或导入到您的方案中。您没有导入任何东西,sqrt-iter也没有在 Scheme 中定义(请参阅 R5RS 或其他资源)。因而sqrt-iter不受约束。

相同的逻辑适用于每个标识符,包括您对word.

在您word?的语法关键字的实现中,let用于引入新的绑定标识符。当您编写时,(number? number?)您正在引入一个新的标识符number?(在左侧)并将其绑定到number?(在右侧)来自环境(它在 Scheme 中定义)。使用let它并没有真正给你买任何东西。您的代码word?可以实现为:

(define (word? x)
  (or (symbol? x) (number? x) (string? x)))   ;; number?
于 2013-10-23T17:00:56.833 回答