6. 条目格式(Entry format)
描述基础库和标准库绑定的章节被用条目组织。每个条目描述一个语言特性或一组相关的特性,其中,一个特性是一个句法结构,或者是一个内置过程。一个条目以一个或多个标题行(header lines)开始,标题行有如下格式:
模板 类别
template category
类别定义了条目描述的绑定的种类,其中类别通常要么是“语法”要么是“过程”。一个条目可以指定子形式或参数的各种限制。对于这些的背景知识,见5.4小节。
6.1. 语法条目
如果类别是“语法”,则这个条目描述一个特定的句法结构,且模板给了这个结构的形式的语法。模板使用类似于第4章BNF规则右侧的符号,且描述了等价于匹配作为句法数据的模板的形式的形式的集合。一些“语法”条目带有一个后缀(扩展(expand)),指明结构的句法关键词是以级别0(level 0)被导出的。否则,句法关键词以级别1被导出;见7.2小节。
一个模板描述的形式的要素(component)被句法变量(syntactic variables)指定,这些句法变量使用尖括号书写,比如:<expression>, <variable>。句法变量中的大小写是无关紧要的。句法变量代表其它的形式或它们的序列。一个句法变量可以在语法中为句法数据(见4.3.1小节)引用一个非终结符,在这种情况下,只有匹配非终结符的形式才被允许在那个位置。比如,<identifier>代表一个必须是标识符的形式。同样,<expression>代表一个句法上是一个合法表达式的形式。其它用在模板中的非终结符被定义为本规范的一部分。
符号
<thing1> ...
代表零个或多个<thing>,且
<thing1> <thing2> ...
代表一个或多个<thing>。
确保一个形式的每一个要素有模板指定的形状是程序员的责任。语法的描述可以表达一个形式的要素的其它限制。通常,这样的限制被格式化成如下形式的短语“<x>必须是(must be)一个…”。再次强调,这些是程序员的责任。只要宏转换涉及扩展形式终结符,检查这些限制被满足就是实现的责任。如果实现检测到一个要素不满足限制,一个条件类型是&syntax的异常被抛出。
6.2. 过程条目
如果类别是“过程”,则条目描述一个过程,标题行给出一个过程调用的模板。模板中参数的名字是斜体。因此,标题行
(vector-ref vector k) 过程
表示一个内建的过程vector-ref接受两个参数,一个是向量vector,和一个精确的非负整数对象k(参见下面的内容)。标题行
(make-vector k) 过程 (make-vector k fill) 过程
表示过程make-vector可以接受一个或两个参数。参数名字的大小写是不敏感的:Vector和vector是一样的。
正如语法模板,标题行的结尾有一个省略号…,如下所示
(= z1 z2 z3 ..) 过程
表示过程接受和最后一个参数名相同类型的任意多个参数。在上面那个例子中,=接受两个或更多的复数对象参数。
一个过程当检测到它没有指定的参数时必须抛出一个条件类型是&assertion的异常,并且,参数规格是详尽的:如果一个过程调用提供的参数数量不匹配过程接受参数的任何一个数量,一个条件类型是 &assertion的异常必须被抛出。
简单地说,本报告遵循如下的惯例,如果一个参数的名字也是一个类型的名字,那么,对应的参数必须是这个类型。比如,上面的vector-ref的标题行指明vector-ref的第一个参数必须是一个向量。下面的命名惯例暗示类型的限制:
obj |
任何对象 |
z |
复数对象 |
x |
实数对象 |
y |
实数对象 |
q |
有理数对象 |
n |
整数对象 |
k |
精确的非负整数对象 |
bool |
布尔(#f或#t) |
octet |
范围在{0, …, 255}的精确的整数对象 |
byte |
范围在{−128, …, 127}的精确的整数对象 |
char |
字符(见11.11小节) |
pair |
点对(见11.9小节) |
vector |
向量(见11.13小节) |
string |
字符串(见11.12小节) |
condition |
条件(见库的第7.2小节) |
bytevector |
字节向量(见库的第2章) |
proc |
过程(见1.6小节) |
其它类型限制通过特定章节描述的变量名字惯例表达。比如,库的第11章为数字的各种子集使用了很多特别的参数变量。
当使用上面列出的限制的时候,确保对应的参数拥有指定的类型是程序员的责任。检查那些类型是实现的责任。
一个叫做表的参数意味着传递一个类型是表(见11.9小节)的参数是程序员的责任。在某种程度上,将检查参数是为了操作执行它的功能适当组织的作为实现的责任是可能的也是合理的。实现必须至少检查参数或者是一个空表或者是一个点对。
过程的描述可以在过程的参数上表达其它的限制。代表性地,这样的限制被格式化成如下形式的短语“x必须是一个…”(或者,否则使用词语“必须”)。
6.3. 实现责任
除了通过命名惯例进行隐含的限制,一个条目可以列出另外的显式的限制。这些显式的限制通常同时描述程序员的责任和实现的责任,程序员的责任意味着程序员必须确保一个形式的子形式是适当的,或一个适当的参数被传递,实现的责任意味着实现必须检查子形式符合规范的限制(如果宏扩展终结的话),或检查参数是不是适当的。通过为参数或子形式打上“实现责任”的标签,一个描述可以显式地列出实现的责任。在这种情况下,在描述的其它部分为这些子形式或参数指定的责任就只是程序员的责任。一个描述实现责任的段落不影响那一段没有描述的实现检查子形式或参数的责任。
6.4. 其它种类的条目
如果类别既不是“语法”也不是“过程”,那么,那个条目描述一个非过程值,且类别描述了这个值的种类。标题行
&who 条件类型
指示&who是一个条件类型。标题行
unquote 辅助语法
指示unquote是一个语法绑定,这个语法绑定只会作为特定周边表达式的部分出现。任何作为一个独立的句法结构或标识符的使用是一个语法错误。和“语法”条目一样,一些“辅助语法”条目带有一个语法后缀(扩展),指明结构的句法关键词以级别1导出。
6.5. 等价的条目
一个条目的描述偶尔会说它和另外一个条目是一样的。这意味着这两个条目是等价的。特别地,它意味着如果两个条目有一样的形式,且从不同的库导出,则两个库的条目可以使用同样的名字导入而没有冲突。
6.6. 求值(Evaluation)的例子
用在程序例子中的符号“⇒”可以被读作“的值是(evaluates to)”。比如,
(* 5 8) ⇒ 40
意味着表达式(* 5 8)的值是对象40。或者,更精确地说:符号序列“(* 5 8)”给出的表达式求值,在导入了相应的库的环境中,得到一个对象,这个对象在外部使用符号的序列“40”表示。见4.3小节对对象外部表示的讨论。
“⇒”符号也在表达式的计算导致错误的时候使用。比如,
(integer->char #xD800) ⇒ &assertion异常
意味着表达式(integer->char #xD800)的求值必须抛出一个条件类型是&assertion的异常。
此外,“⇒”符号也被用作显式地说明一个表达式的值是未定义的。比如:
(eqv? "" "") ⇒ 未定义的
通常,例子仅仅阐述了条目中指定的行为。可是在有些时候,它们帮助规范中模糊不清的地方消歧义,所以此时它们是规范性的。注意,在有些情况下,特别是在非精确数字对象的情况下,返回值只会有条件地或近似的指明。比如
(atan -inf.0)
⇒ -1.5707963267948965 ; 近似地
6.7. 命名惯例
依照惯例,将值存进上次分配的位置(见5.10小节)的过程的名字通常使用“!”。
依照惯例,“->”出现在以一个类型的对象作为参数,返回另一个类型的类似对象的过程名字中。比如,list->vector接受一个表并返回一个元素和此表一样的向量。
按照惯例,谓词(predicates)—总是返回一个布尔的过程—以“?”结尾,只有当名字不包含任何字母的时候,谓词才不以问号结尾。
按照惯例,复合名字的要素使用“-”进行分隔。尤其,是一个实际单词或可以像一个实际单词一样发音的单词的前缀会跟着一个连字符,除非跟在连字符后面的第一个字符不是一个字母,在这种情况下,连字符可以省略。简单地说,连字符不会跟在不可发音的前缀(“fx”和“fl”)后面。
按照惯例,条件类型的名字以“&”开头。