UP | HOME

1 简介

Table of Contents

Lisp 历史

Lisp(列表处理语言)最早于20世纪50年代末在麻省理工学院人工智能研究所开发

Lisp语言强大的功能使其非常适合用于其他用途,例如编写编辑命令

多年来已经构建了数十个Lisp实现,每个都有自己的特性。他们中的许多人都受到了Maclisp的启发,该书于20世纪60年代在麻省理工学院的MAC项目中写成。最终,Maclisp后代的实现者走到了一起,为Lisp系统开发了一个标准,称为Common Lisp。与此同时,麻省理工学院的格里·苏斯曼(GerrySussman)和盖伊·斯蒂尔(GuySteele)开发了一种简化但功能强大的Lisp方言,名为Scheme

GNU Emacs Lisp主要受Maclisp的启发,也有一点受Common Lisp的启发

如果您了解Common Lisp,您将注意到许多相似之处。然而,为了减少GNU Emacs的内存需求,Common Lisp的许多特性被省略或简化

有时,简化是如此剧烈,以至于Common Lisp用户可能会感到非常困惑

我们偶尔会指出GNU Emacs Lisp与Common Lisp的区别。如果你不懂Common Lisp,不要担心它;本手册是独立的

通过 cl-lib 库可以获得一定数量的Common Lisp仿真。请参见Common Lisp扩展中的概述

Emacs Lisp完全不受Scheme的影响;但是GNU项目有一个方案的实现,叫做 Guile 。我们在所有要求可扩展性的新GNU软件中使用它

约定

条款

在本手册中

  • 短语 Lisp readerLisp printer 指的是 Lisp 中将 Lisp 对象的文本表示形式转换为实际 Lisp 对象的那些例程,反之亦然

    有关详细信息,请参阅打印表示和读取语法
    
  • 你,阅读本手册的人,被认为是 程序员,被称为
  • 用户是使用 Lisp 程序的人,包括您编写的程序

Lisp 代码示例 的格式如下:

(list 1 2 3)

代表元句法 变量的名称 ,或所描述 函数的参数 ,格式如下:

first-number 

nil和 t

在 Emacs Lisp 中,符号 nil 具有三种不同的含义:

  1. 它是一个名称为 nil符号
  2. 逻辑真值
  3. 它是一个 空列表 零元素的列表
当用作变量时, nil 始终具有 nil 值

就 Lisp 阅读器而言, ()nil 是相同的:它们代表同一个对象, 符号 nil

书写符号的不同方式完全适用于人类读者。在 Lisp 阅读器读取 () 或 nil 之后,无法确定程序员实际编写的表示形式

在本手册中:

  • 当我们想强调它表示空列表时,我们写 ()
  • 当我们想强调它表示真值 false 时,我们写 nil
(cons 'foo ())                ; Emphasize the empty list
(setq foo-flag nil)           ; Emphasize the truth value false
这也是在 Lisp 程序中使用的一个很好的约定

在期望真值的情况下, 任何非零值 都被认为是 真值 。但是, t 是表示 真值 true 的首选方式 。当你需要选择一个代表真实的值,并且没有其他选择依据时,使用 t 。符号 t 始终具有值 t

在 Emacs Lisp 中, nil 和 t 是特殊符号,它们总是对自己求值

这样您就不需要引用它们来将它们用作程序中的常量

尝试更改它们的值会导致设置常量错误。请参阅永不改变的变量

booleanp 函数

Function: booleanp object

如果 object 是两个规范布尔值 t 或 nil 之一,则返回非 nil

评估符号

您可以评估的 Lisp 表达式 称为 形式 form 。计算一个 形式 ( form ) 总是会产生一个 结果 ,它是一个 Lisp 对象 。在本手册的示例中,这用 表示:

(car '(1 2))
⇒ 1
您可以将其解读为 (car '(1 2)) 计算结果为 1

当一个 形式 ( form ) 是一个 宏调用 时,它会 扩展 为一个 新的 形式 ( form ) 供 Lisp 计算。我们用 显示扩展的结果。我们可能会或可能不会显示扩展 形式 ( form ) 的评估结果

(third '(a b c))(car (cdr (cdr '(a b c))))
⇒ c

为了帮助描述一种 形式 ( form ) ,我们有时会展示另一种产生相同结果的 形式 ( form ) 。两种 形式 ( form ) 的 精确等价 表示

(make-sparse-keymap)(list 'keymap)

打印符号

本手册中的许多示例在评估时都会打印文本

如果您通过在示例的右括号后键入 C-j 在 Lisp 交互缓冲区(例如缓冲区 *scratch*)中执行示例代码,则打印的文本将插入到缓冲区中

如果您通过其他方式执行示例(例如通过评估函数 eval-region ),则打印的文本将显示在回显区域中

本手册中的示例用 -| 表示打印文本,无论该文本位于何处。通过评估表单返回的值在单独的行后面加上

(progn (prin1 'foo) (princ "\n") (prin1 'bar))
-| foo
-| bar
⇒ bar

错误信息

一些示例表明错误。这通常会在 回显区域 中显示错误消息。我们在以 error→ 开头的行上显示错误消息

(+ 23 'x)
error→ Wrong type argument: number-or-marker-p, x
请注意, error→ 本身不会出现在回显区域中

缓冲区文本符号

一些示例通过显示文本的前后版本来描述对缓冲区内容的修改。这些示例显示了 包含缓冲区名称的两行破折号之间 的缓冲区内容。此外, * 表示点的位置

---------- Buffer: foo ----------
This is the ∗contents of foo.
---------- Buffer: foo ----------

(insert "changed ")
⇒ nil
---------- Buffer: foo ----------
This is the changed ∗contents of foo.
---------- Buffer: foo ----------
当然,点的符号不是缓冲区中文本的一部分;它表示点当前所在的两个字符之间的位置

说明格式

本手册以统一的格式描述了 函数变量命令用户选项特殊形式

  • 描述的第一行包含 项目的名称 ,后跟其 参数 (如果有)
  • 类别(函数、变量或其他)出现在行首
  • 描述在随后的行中
  • 有时带有示例

示例函数描述

在函数描述中,被描述函数的名称首先出现。它在同一行后面是参数名称列表。这些名称也用于描述的主体,代表参数的值

参数列表中关键字 &optional 的出现表明 后面的参数可以省略

省略的参数默认为 nil 。调用函数时不要写 &optional 

关键字 &rest (后面必须跟一个参数名)表示后面可以跟 任意数量的参数&rest 后面的单个参数名称 作为其值 接收 传递给函数的所有剩余参数的列表

调用函数时不要写 &rest 

下面是一个虚构函数 foo 的描述:

Function: foo integer1 &optional integer2 &rest integers

函数 foo 从 integer2 中减去 integer1 ,然后将所有其余参数添加到结果中。如果未提供 integer2 ,则默认使用数字 19

(foo 1 5 3 9)
⇒ 16
(foo 5)
⇒ 14

更普遍,

(foo w x y…)(+ (- x w) y…)

按照惯例:

  • 任何名称包含类型名称(例如,整数、整数 1 或缓冲区)的参数都应属于该类型
  • 一个类型(例如缓冲区)的复数通常表示该类型的对象列表
  • 名为 object 的参数可以是任何类型

    有关 Emacs 对象类型的列表,请参阅 Lisp 数据类型
    
  • 具有任何其他名称(例如,新文件)的参数是特定于函数的
  • 如果函数有文档字符串,则应在此处描述参数的类型
有关 &optional 和 &rest 修改的参数的更完整描述,请参阅 Lambda 表达式

命令特殊形式的描述 具有相同的格式,但 函数 一词分别被 命令特殊形式 取代:

  • 命令只是可以交互调用的简单函数
  • 宏处理它们的参数与函数不同(不评估参数),但以相同的方式呈现

宏和特殊形式的描述使用更复杂的符号来指定可选和重复参数,因为它们可以以更复杂的方式将参数列表分解为单独的参数:

  • '[optional-arg]' 表示 optional-arg 是 可选
  • 'repeated-args…' 代表 零个或多个参数
  • 多个参数被分组到列表结构的其他级别 时,使用 括号

这是一个特殊例子:

Special Form: count-loop (var [from to [inc]]) body… 

在这种特殊形式中:

  • 参数 from 和 to 是可选的,但必须同时存在或不存在
    • 如果它们存在,也可以选择指定 inc
    • 这些参数与参数 var 一起分组到一个列表中,以将它们与 body 区分开来
  • 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)))

示例变量描述

变量 是可以 绑定 (或设置)到对象的名称。 变量绑定的对象 称为 ;我们也说那个变量持有那个值。尽管几乎所有变量都可以由用户设置,但某些变量是专门存在的,因此用户可以更改它们;这些被称为 用户选项 。普通变量和用户选项使用类似于 函数的格式 来描述,除了没有参数。以下是虚构的电动未来图变量的描述:

Variable: electric-future-map

此变量的值是 Electric Command Future 模式使用的完整键盘映射。此地图中的功能允许您编辑尚未考虑执行的命令

用户选项描述具有相同的格式,但 变量用户选项 取代

版本信息

这些工具提供有关正在使用的 Emacs 版本的信息:

Command: emacs-version &optional here

这个函数返回一个描述正在运行的 Emacs 版本的字符串。在错误报告中包含此字符串很有用

(emacs-version)"GNU Emacs 26.1 (build 1, x86_64-unknown-linux-gnu,
             GTK+ Version 3.16) of 2017-06-01"

如果 here 不是 nil ,则将文本插入缓冲区中的 point 之前,并返回 nil 。当这个函数被交互调用时,它会在回显区域打印相同的信息,但是给出一个前缀参数使得这里非零

Variable: emacs-build-time

这个变量的值表示 Emacs 的构建时间。它使用当前时间的样式(参见时间),如果信息不可用,则为 nil

emacs-build-time
⇒ (20614 63694 515336 438000)

Variable: emacs-version

这个变量的值是正在运行的 Emacs 的版本。它是一个字符串,例如 26.1 。具有三个数字分量的值,例如 26.0.91 ,表示未发布的测试版本

在 Emacs 26.1 之前,字符串包含一个额外的 final 组件,其整数现在存储在 emacs-build-number 中;例如, 25.1.1 

Variable: emacs-major-version

Emacs 的主版本号,以整数表示。对于 Emacs 版本 23.1 ,该值为 23

Variable: emacs-minor-version

Emacs 的次要版本号,为整数。对于 Emacs 版本 23.1 ,该值为 1

Variable: emacs-build-number

每次在同一目录中构建 Emacs 时递增的整数(无需清理)。这仅在开发 Emacs 时具有相关性

Variable: emacs-repository-version

一个字符串,它给出了构建 Emacs 的代码库版本。如果 Emacs 是在版本控制之外构建的,则该值为 nil

Variable: emacs-repository-branch

一个字符串,它给出了构建 Emacs 的代码库分支。在大多数情况下,这是 master 。如果 Emacs 是在版本控制之外构建的,则该值为 nil

致谢

本手册最初由GNU手册小组的志愿者Robert Krawitz、Bil Lewis、Dan LaLiberte、Richard M.Stallman和Chris Welty历时数年编写。在国防高级研究计划局ARPA 6082项目(由计算逻辑公司的Warren A.Hunt Jr负责)的支持下,Robert J.Chassell协助审查和编辑了该手册。此后,Miles Bader、Lars Brinkhoff、Chong Yidong、Kenichi Handa、Lute Kamstra、Juri Linkov、Glenn Morris、Thien Thi Nguyen、Dan Nicolaescu、Martin Rudaliss、,Kim F.Storm、Luc Teirlinck、Eli Zaretskii等人亦有参与。

参与更正的人员有Drew Adams、Juanma Barrankero、Karl Berry、Jim Blandy、Bard Bloom、Stephane Boucher、David Boyes、Alan Carroll、Richard Davis、Lawrence R.Dodd、Peter Doornbosch、David A.Duff、Chris Eich、Beverly Erlebacher、David Eckelkamp、Ralf Fassel、Eirik Fuller、Stephen Gildea、Bob Glickstein、Eric Hanchrow、Jesper Harder、George Hartzell、Nathan Hess、Masayuki Ida、,Dan Jacobson、Jak Kirman、Bob Knighten、Frederick M.Korz、Joe Lammens、Glenn M.Lewis、K.Richard Magill、Brian Marick、Roland McGrath、Stefan Monnier、Skip Montanaro、John Gardiner Myers、Thomas A.Peterson、Francesco Potortì、Friedrich Pukelsheim、Arnold D.Robbins、Raul Rockwell、Jason Rumney、Per Starbä、Shinichrou Sugou、Kimmo Suominen、Edward Tharp、Bill Trost、Rickard Westman、,Jean White、Eduard Wiebe、Matthew Wilding、Carl Witty、Dale Worley、Rusty Wright和David D.Zuhn等人。

有关贡献者的更完整列表,请参阅Emacs源存储库中的相关更改日志条目
Next: 数据类型 Home: Emacs Lisp 手册