> For the complete documentation index, see [llms.txt](https://emacs-lisp.ivory.cafe/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://emacs-lisp.ivory.cafe/kong-zhi-jie-gou/untitled.md).

# 11.1 顺序执行（DONE）

按照表达式出现的顺序对其求值是最常见的控制传递方式。在一些语境中，鼻疽函数体，这种控制流是自动的。但在其他地方，你必须使用progn来进行顺序控制，这是Lisp中最简单的控制结构。

一个progn特殊表达式通常看起来类似这样：

```
(progn a b c ...)
```

其含义是按顺序依次对表达式a、b、c等等进行求值。这些表达式称为progn特殊表达式的主体。最后那个表达式的求值结果将会作为整个progn结构的求值结果返回。(progn)将返回nil。

在Lisp的早期，progn是唯一的依次求值并返回最后表达式求值结果的方式。时间久了，程序员发现在函数中，progn使用的太过频繁。（因为那个时候，函数体中只能有一个表达式）因此，后续函数体的实现被隐式的嵌入了progn：也就是说，在函数体中可以直接书写多个表达式，就像progn那样。类似的，很多其他的控制接口中也逐渐内嵌了progn的隐式实现。结果就是，我们再也不用像很多年前那样大量使用progn。现在，通常只会在unwind-protect，and，or或者在某些if的then语句中使用progn。

\[Special Form] progn forms...

该特殊表达式会按文本序逐次对表达式求值，并将最后一个表达式的求值结果作为整个progn的求值结果。

```lisp
(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"
```

progn还有两个变体，区别是这些变体返回不同的值：

\[Special Form] prog1 form1 forms...

该特殊表达式会对form1求值，然后逐次对剩下的表达式求值，并将第一个表达式的求值结果作为整个prog1的求值结果。

```lisp
(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中抛出第一个值的例子：

```lisp
(prog1 (car x) (setq x (cdr x)))
```

\[Special Form] prog2 form1 form2 forms...

该特殊表达式会对form1、form2求值，然后逐次对剩下的表达式求值，并将第二个表达式的求值结果作为整个prog2的求值结果。

```lisp
(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"
```
