这本书描述了 Chez Scheme 给 Scheme 修订6报告 (R6RS) 的扩展。它也 包含了对标准对精确对概括和 Chez Scheme 的句法形式和过程,并给出了每个句法形式的句法 和每个过程所接受的参数数量和类型。R6RS 标准特性的细节可以在 《Scheme 编程语言,第四版》 (TSPL4) 或 Scheme 修订6报告 里找到。《Scheme 编程语言,第四版》也包含了大量的对 Scheme 语言的介绍和许多或短或长的例子。
这个文档的大部分也可以同样地应用于 Petite Chez Scheme,它可以完全兼容整个 Chez Scheme 系统,只不过使用了很快的解释器代替了 Chez Scheme 的增量式原生代码编译器。 只要不涉及编译器调用,那么给 Chez Scheme 写的程序可以原封不动地运行于 Petite Chez Scheme 里。 事实上,Petite Chez Scheme 和 Chez Scheme 构建于相同的源代码,除了包含编译器代码, 其它的都一样。在2.8节,详细地讨论了这个差别的影响。
本章剩下的部分包括 Chez Scheme 对 Scheme 句法的扩展 (第1.1节),本书用到的符号约定 (第1.2节), 用来定制系统的参数 (第1.3节),和在哪里可以找到更多关于 Chez Scheme 的信息 (第1.4节)。
第二章描述了如何用 Chez Scheme 开发程序,写脚本,交付应用,加上如何使编译器尽可能 生成更高效的代码。第三章描述了调试和对象检查工具。第四章记录了用于和不同进程或其它语言写的 代码如何交互的文档。第五章描述了绑定句法形式。第六章记录控制结构的文档。第七章记录了非数值 对象的操作的文档,而第八章记录了多种数值操作,包括高效的类型明确的操作。第九章描述了输入/输出 操作和一般性端口,一般性端口允许通过任意的输入输出语义来定义其它端口。第十章讨论了 R6RS 库 和顶层程序如何加载进 Chez Scheme,并可同时使用其众多的用于控制和追踪加载进程的特性。第 十一章描述了句法扩展和模块。第十二章描述了系统操作,例如与操作系统的交互和定制 Chez Scheme 的用户接口。第十三章描述了如何调用和控制存储管理系统和记录了守卫者和 weak pair 的文档。第十四章描述了 Chez Scheme 的表达式编辑器和如何定制它。第十五章记录了构成 Chez Scheme 原生线程 系统接口的过程和句法形式。最后,第十六章描述了很多兼容特性。
这本书后面包含了参考书目,句法形式的总结,和索引。出现在句法形式总结中的页码和出现在索引中的 斜体页码指出了句法形式和过程在文中正式地被定义的位置。句法形式总结和索引包含了来自 TSPL4 的 条目,因此它们包含了 Chez Scheme 整个的特性集合。TSPL4 条目的页码标记有前缀“t”。
这本书和 TSPL4 的在线版本和勘误可以在这里找到 www.scheme.com。
感谢:Michael Adams, Mike Ashley, Carl Bruggeman, Bob Burger, Sam Daniel,
George Davidson, Matthew Flatt, Aziz Ghuloum, Bob Hieb, Andy Keep,
和 Oscar Waddell 对开发 Chez Scheme 作出的重大贡献。Chez Scheme 的表达式编辑器
基于 C. David Boyer 从 1989 年到 1994 年开发的给 Scheme 的命令行编辑器。文件压缩用到
了 Jean-loup Gailly 和 Mark Adler 开发的 zlib 压缩库。实现 list
和 vector
排序的子程序基于 Olin Shiver 的机会主义合并排序算法和实现。Michael Lenaghan 为本书
的早期草稿提供了若干修正意见。这本书记录的很多特性都是现在的 Chez Scheme 用户建议的,
并且用户的许多评论也提升了本书,在正文内容方面。欢迎提出更多可以提升 Chez Scheme 和本书
的意见。
Chez Scheme 在对象 (数据) 和句法形式层面都继承自 Scheme。在对象层面上,Chez Scheme
支持包含非标准字符的额外的符号表示,非十进制的浮点数和科学记法,显式长度的 vector
,共享的
和循环的 structure
,record
,box
等等。接下来将描述这些扩展。句法形式层面的扩展
将会在贯穿全书和句法形式总结中描述,书后面也会出现。
Chez Scheme 以若干方式方法继承了标识符的语法。首先,组成标识符名字的字符序列可以以数字,句号,
加号和减号开头,只要这个序列不被解析为数字就可以。举个例子,0abc
,+++
,和 ..
在
Chez Scheme 里均是有效的标识符。其次,单字符序列的 {
和 }
也是标识符。再次,包含任意
字符的可能会被用 \
或 |
转义后打印。\
用于转义单字符(除了 ‘x’,因为 \x
用于标记十六进制
标量值的开头),而 |
被用来转义一组跟着它到匹配到下个 |
的字符。举个例子,\||\|
是一个
名字包含两个字符,由字符 |
后跟字符 \
组成的标识符,|hit me!|
是一个名字中包含一个空白的标识符。
另外,gensym
会打印出用 #{
和 }
括号括起来的“美观”和“独特”的两种名字,例如,
#{g1426 e5g1c94g642dssw-a}
。也可以只用带前缀 #:
的“美观”名字打印,例如 #:g1426
。
从 2 到 36 的任意基数可以用 #nr
来指定,这里的 n
是基数。大小写不重要,因此,使用 #nR
也是
一样的。数字值从 10 到 35 也可以用或小写或大写到字母字符来指定,就像十六进制数字那样。举个例子,
#36rZZ
就是 35 × 36 + 35
或 1295。
Chez Scheme 也允许非十进制数字打印成浮点数或科学记法。举个例子,#o1.4
等于 1.5
,
#b1e10
等于 4.0
。数字优先于指数符号,因此,#x1e20
就只简单的是四个数的十六进制数字,等于
7712
。
另外,附加了一些除标准知名字符如 #\alarm
, #\backspace
, #\delete
, #\esc
,
#\linefeed
, #\newline
, #\page
, #\return
, #\space
, 和 #\tab
之外,
Chez Scheme 还可以识别 #\bel
, #\ls
, #\nel
, #\nul
, #\rubout
,
和 #\vt
(或 #\vtab
)。标量值小于 256 的字符也可以以八进制语法即由前缀 #\
后跟一个三个八进制
数字的序列打印。举个例子,#\000
等于 #\nul
。
Chez Scheme 的 fxvector
,或者固定数 vector
,将以类似 vector
但用前缀 #vfx(
代替了
#(
打印。vector
,bytevector
和 fxvector
也可以以显式长度前缀打印,并且当指定了显式长度前缀,
尾部重复元素也将被省略。举个例子,#(a b c)
也可以打印成 #3(a b c)
,长度 100 元素全是零的 vector
可以打印成 #100(0)
。
Chez Scheme 的 box
将以 #&
前缀打印,例如,#&17
是一个包含整数 17
的 box
。
record
将以 #[类型名 数据成员 ...]
的语法打印,这里的符号 类型名
是 record
类型的名字,
field ...
是 record
的数据成员内容的打印表示。
共享结构可以打印为前缀 #n=
的图标记,循环结构可以打印为前缀 #n#
的引用。#n=
用来标记东西作为
输入,#n#
用来引用标记为 n
的东西。举个例子,'(#1=(a) . #1#)
是一个 pair,其 car
和
cdr
乃同一个列表,#0=(a . #0#)
是一个循环列表,也就是说,它的 cdr
是它自己。
$primitive
形式也可以像 quote
一样可以简写,用前缀 #%
。举个例子,#%car
等价于
($primitive car)
,#2%car
等价于 ($primitive 2 car)
,#3%car
等价于 ($primitive 3 car)
。
Chez Scheme 的文件结束对象打印为 #!eof
。如果文件结束对象出现在正被加载的文件中的任何数据对象之外,
load
将以文件真正结束对待,即在这个点停止加载。因此可以通过在文件中间插入 #!eof
来方便地追踪加载时错误。
Weak pair 中损坏的指针表示为 broken weak pair 对象,打印为 #!bwp
。
作为对标准分割符(空白,开闭圆括号,开闭方括号,双引号,分号和 #
)的补充,Chez Scheme 也可以将开闭花括号,
单引号,反引号,逗号视作分割符。
在输入流中看到 #!r6rs
注释指令后,上面描述的 Chez Scheme 的词法扩展将失效,除非在之前看到 #!chezscheme
指令。每个通过 import
隐式加载的库和每个通过 --program
命令行选项,scheme-script
命令,或 load-program
过程加载的 RNRS 顶级程序都将会以它以隐式的 #!r6rs
注释指令开头来对待。
按照修订报告6的要求,符号和字符名字的大小写通常都是重要的。在相同的输入流里,就像被 string-foldcase
处理过
一样,#!fold-case
注释指令后的名字都是小写的,除非看到 #!no-fold-case
。没有指令的时候,且 case-sensitive
参数被设置成 #f
时,名字也都是小写的。
打印机被 write
, put-datum
, pretty-print
, 和 format ~s
选项调用总是用标准语法打印修订报告6
的标准对象,除非通过设置一个打印参数来请求不同的行为。举个例子,要使用上面描述的十六进制标量值转义序列来打印
Chez Scheme 扩展标识符语法的符号, 除非设置 print-extended-identifiers
参数为真。类似的,除非设置
print-vector-length
参数为真,否则不会打印显式长度或抑制尾部重复元素。