A forma especial progn está especialmente vocacionada para este género de utilização. Ela recebe um conjunto de expressões que avalia sequencialmente retornando o valor da última. Desta forma é possível incluir várias acções no consequente ou alternativa de um if, por exemplo.
(if (> 3 2) (progn (print 'estou-no-consequente) (+ 2 3)) (progn (print 'estou na alternativa) (* 4 5)))
Algumas das formas especiais do Lisp incluem um progn implícito. Vimos atrás um exemplo de um let que realizava quatro operações em sequência. Isto implica que o let e, por arrastamento, as lambdas e tudo o que for definido com defun, possuem também a capacidade de realizar operações em sequência. O cond está também nesta categoria. A sua sintaxe é, na realidade, a seguinte:
(cond (condição-1 expressão-11...expressão-1l) (condição-2 expressão-21...expressão-2m)(condição-n expressão-n1...expressão-nk))
O cond testa cada uma das condições em sequência, e quando uma delas avalia para verdade, são avaliadas todas as expressões da cláusula correpondente sendo devolvido o valor da última dessas expressões.
Usando o cond, o exemplo anterior ficará mais elegante:
(cond ((> 3 2) (print 'estou-no-consequente) (+ 2 3)) (t (print 'estou na alternativa) (* 4 5)))
A forma especial prog1 é semelhante ao progn. Ela recebe um conjunto de expressões que avalia sequencialmente retornando o valor da primeira. A expressão equivalente ao exemplo anterior mas utilizando o prog1 será:
(if (> 3 2) (prog1 (+ 2 3) (print 'estou-no-consequente)) (prog1 (* 4 5) (print 'estou na alternativa)))
Note-se que a ordem de avaliação das expressões de um prog1 é igual à de um progn. Apenas o valor retornado é diferente: é o primeiro no caso do prog1 e o último no caso do progn.
A sequenciação é também suportada por qualquer lambda. Em consequência, as formas especiais que implicam a criação de lambdas, como o let e o próprio defun permitem também especificar mais do que uma expressão, sendo estas avaliadas em sequência e devolvido o valor da última.