在本页中:
1.1 与 Racket 进行交互
1.2 定义与交互
1.3 创建可执行文件
1.4 Lisp/  Scheme 经验者注意

1 欢迎来到 Racket

根据视角的不同,Racket 可以是:

在没有歧义时,我们就简单地使用 Racket

Racket 的主要工具包括:

通常,你可以用 DrRacket 来探索 Racket 语言,特别是在开始阶段。 根据自己偏好,你也可以按照自己的偏好使用命令行 racket 解释器和你喜欢的文本编辑器,详情请参阅Command-Line Tools and Your Editor of Choice。 本文档中其余介绍语言的部分大都与你选择的编辑器无关。

如果你使用 DrRacket,就需要选择适当的语言,因为 DrRacket 支持多种 Racket 变体和其它语言。如果你从未使用过 DrRacket,请启动它,并在 DrRacket 上方的文本区内输入

#lang racket

之后点击文本区上方的运行按钮,这样 DrRacket 就明白你要使用 Racket 的正常变体了(这里的“正常”是相对于更小的 racket/base 或其它可用的变体而言的)。

More Rackets一节中描述了其它可用的变体。

如果你曾经在 DrRacket 中编写过不以 #lang 开头的程序,那么 DrRacket 会记住你上一次使用的语言,而非根据 #lang 来推断。此时,请点击 语言|选择语言...

1.1 与 Racket 进行交互

DrRacket 下方的文本区和 racket 命令行程序(在无选项启动时) 都可以视作一种计算器。你只需输入 Racket 表达式,敲下回车键,答案就打印出来了。 按照 Racket 的术语,这种计算器叫做读取-求值-打印 循环 (read-eval-print loop),简称 REPL

数字本身就是就是表达式,其答案就是该数字。

> 5

5

字符串也是求值为其自身的表达式。字符串写在两个双引号之间:

> "Hello, world!"

"Hello, world!"

Racket 使用圆括号来括住较大的表达式—即除常量之外的几乎任何表达式。 例如,一个函数调用写作:开括号,函数名,参数表达式和闭括号。 以下表达式以参数 "the boy out of the country"47 调用了内建函数 substring

> (substring "the boy out of the country" 4 7)

"boy"

1.2 定义与交互

你可以通过 define 形式来定义自己的函数,让它像 substring 那样工作:

(define (extract str)
  (substring str 4 7))

 

> (extract "the boy out of the country")

"boy"

> (extract "the country out of the boy")

"cou"

尽管你可以在 REPL 中对 define 形式进行求值, 然而定义通常是程序的一部分,你可能想要保留它以备后用。因此在 DrRacket 中,通常你应将定义连同 #lang 前缀一起放在上方的文本区, 即定义区内:

#lang racket
 
(define (extract str)
  (substring str 4 7))

如果调用 (extract "the boy") 是你的程序主要活动的一部分, 那么它也应当放在定义区内。但如果它只是你用来测试 extract 的示例表达式,那么你可能更愿意将定义区保持为如上状态,点击运行, 然后在 REPL 中对 (extract "the boy") 求值。

在使用命令行 racket 而非 DrRacket 时,你应当用编辑器将以上文本保存在文件中。 如果你将它保存为 "extract.rkt",那么在同一目录下执行 racket 之后,就会对以下序列求值:

如果你使用 xrepl,那么可以用 ,enter extract.rkt.

> (enter! "extract.rkt")
> (extract "the gal out of the city")

"gal"

enter! 形式会加载该代码并将求值上下文切换到该模块中,就像 DrRacket 的运行按钮那样。

1.3 创建可执行文件

如果你的文件(或 DrRacket 的 定义区)中包含

#lang racket
 
(define (extract str)
  (substring str 4 7))
 
(extract "the cat out of the bag")

那么它就是个在运行时会打印“cat”的完整程序。你可以使用 DrRacket 或在 racket 中使用 racket 来运行该程序。但如果该程序保存在 src-filename 中,你也可以在命令行中运行它:

  racket src-filename

你有几种可选的方式将程序打包成可执行文,:

1.4 Lisp/Scheme 经验者注意

如果你对 Scheme 或 Lisp 有所了解,那么你可能会试图将

(define (extract str)
  (substring str 4 7))

放在 "extract.rktl" 中并以如下方式运行 racket

> (load "extract.rktl")
> (extract "the dog out")

"dog"

这样确实可以工作,因为 racket 会模拟出传统的 Lisp 环境。 不过我们强烈建议你不要在模块之外使用 load 或编写程序。

在模块外编写程序会结合糟糕的错误消息、低劣性能和笨拙的脚本来运行程序。 这些问题并非针对于 racket,它们是传统上层环境的根本限制, 历史上 Scheme 和 Lisp 的实现与造成这些限制的特设(ad-hoc)命令行参数、 编译器指令和构建工具作过斗争。模块系统的设计就是用来避免这些问题的, 因此从长远来看,以 #lang 开始会让 Racket 的使用体验更加愉快。