11.1 Последовательность

Выполнение форм в порядке их появления является наиболее распространенным способом передачи управления от одной формы к другой. В некоторых контекстах, например, в теле функции, это происходит автоматически. В других местах вам необходимо использовать конструкцию управляющей структуры, чтобы это сделать: 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 или в части then конструкции if.

Специальная форма: 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"

Две другие конструкции также вычисляют серию форм, но возвращают разные значения:

Специальная форма: 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)))
Специальная форма: prog2 form1 form2 forms…

Эта специальная форма вычисляет form1, form2 и все последующие 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"