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的求值结果。

(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的求值结果。

(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...

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

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

最后更新于