在函数描述中,首先出现的是被描述函数的名称,同一行紧接着是参数名列表。这些参数名也会在描述正文中使用,用来代表参数的值。
参数列表中出现关键字 &optional,表示其后的参数可以省略(省略的参数默认为 nil)。调用函数时不要写 &optional。
关键字 &rest(其后必须紧跟一个参数名)表示后面可以跟任意数量的参数。&rest 后面的这个参数名,会以列表形式接收传给函数的所有剩余参数。调用函数时不要写 &rest。
下面是一个虚构函数 foo 的描述:
函数 foo 用 integer2 减去 integer1,然后将其余所有参数加到结果上。如果没有提供 integer2,则默认使用数值 19。
(foo 1 5 3 9)
⇒ 16
(foo 5)
⇒ 14
更普遍的,
(foo w x y...) ≡ (+ (- x w) y...)
按照约定,任何名称中包含类型名的参数(例如 integer、integer1 或 buffer),都要求属于该类型。类型的复数形式(如 buffers)通常表示该类型对象的列表。名为 object 的参数可以是任意类型。(有关 Emacs 对象类型列表,see Lisp 数据类型。)名称带有其他含义的参数(如 new-file)则是该函数专用的;如果函数有文档字符串,其中会说明参数类型(see Documentation)。
关于被 &optional 和 &rest 修饰的参数更完整的说明,See Lambda 表达式。
命令、宏和特殊形式的描述格式相同,只是把开头的 ‘Function’ 分别换成‘Command’、‘Macro’ 或 ‘Special Form’。命令只是可以交互式调用的函数;宏对参数的处理方式与函数不同(参数不被求值),但描述形式一致。
宏和特殊形式的描述会使用更复杂的表示法来指定可选参数和重复参数,因为它们可以用更复杂的方式把参数列表拆分为独立参数。‘[optional-arg]’ 表示 ‘optional-arg’ 是可选参数;‘repeated-args…’ 表示零个或多个参数。当多个参数被分组为更深层的列表结构时,会使用圆括号。示例如下:
这个虚构的特殊形式实现一个循环,每次迭代先执行 body 中的表达式,再对变量 var 递增。第一次迭代时,变量取值为 from;后续迭代每次加 1(若指定了 inc 则按 inc 递增)。如果 var 等于 to,则在执行 body 之前退出循环。示例:
(count-loop (i 0 10) (prin1 i) (princ " ") (prin1 (aref vector i)) (terpri))
如果省略 from 和 to,则循环开始前将 var 绑定为 nil,且每次迭代开始时,若 var 非-nil 则退出循环。示例:
(count-loop (done)
(if (pending)
(fixit)
(setq done t)))
在这个特殊形式里,参数 from 和 to 是可选的,但必须同时出现或同时省略。如果它们出现,还可以额外指定 inc。这些参数与 var 一起被放在一个列表里,以区别于 body — body 包含该形式中所有剩余元素。