11.1 顺序执行

按照形式出现的顺序对其求值,是控制流程从一个形式传递到另一个形式最常用的方式。在某些上下文(例如函数体)中,这一过程会自动发生。在其他场景下,你则必须使用一种控制结构语法来实现这一点:progn—— 这是 Lisp 中最简单的控制结构。

progn 特殊形式的语法如下:

(progn a b c ...)

它的作用是按顺序执行形式 abc 等。这些形式被称为 progn 形式的 主体(body)。主体中最后一个形式的求值结果会成为整个 progn 的返回值。(progn)(无参数调用时)返回 nil

在 Lisp 发展早期,progn 是唯一能连续执行两个或多个形式、并取用最后一个形式求值结果的方式。但程序员们发现,他们经常需要在函数体中使用 progn—— 因为当时的函数体只允许包含一个形式。因此,函数体被设计为隐式的 progn:就像真正的 progn 主体一样,函数体中可以包含多个形式。许多其他控制结构也同样内置了隐式的 progn。这使得 progn 的使用频率远不如多年前那么高。如今它最常用的场景是在 unwind-protectandor 内部,或是 ifthen 分支中。

Special Form: progn forms…

该特殊形式会按照文本顺序对所有 forms 依次求值,并返回最后一个形式的求值结果。

(progn (print "The first form")
       (print "The second form")
       (print "The third form"))
     ⊣ "The first form"
     ⊣ "The second form"
     ⊣ "The third form"
⇒ "The third form"

另外两个结构同样会对一系列形式进行求值,但返回的值不同:

Special Form: prog1 form1 forms…

该特殊形式按照文本顺序对 form1 以及所有 forms 依次求值,并返回 form1 的结果。

(prog1 (print "The first form")
       (print "The second form")
       (print "The third form"))
     ⊣ "The first form"
     ⊣ "The second form"
     ⊣ "The third form"
⇒ "The first form"

有一种方法可以移除变量 x 所指向列表中的第一个元素,并返回这个被移除的元素的值:

(prog1 (car x) (setq x (cdr x)))
Special Form: prog2 form1 form2 forms…

该特殊形式会按照文本顺序依次对 form1form2 以及后续所有 forms 进行求值,并返回 form2 的求值结果。

(prog2 (print "The first form")
       (print "The second form")
       (print "The third form"))
     ⊣ "The first form"
     ⊣ "The second form"
     ⊣ "The third form"
⇒ "The second form"

emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike