Le bloc le plus simple est progn. C'est un opérateur spécial acceptant un nombre arbitraire non nul d'arguments. Chaque argument est une expression et ces expressions sont évaluées séquentiellement. La valeur de toutes les expressions sauf la dernière est perdue. La valeur de l'expression progn toute entière sera la valeur de la dernière expression de la séquence (d'où le `n' de progn : la valeur de la n-ième expression est renvoyée). Puisque leur valeurs sont perdues, les premières expressions devraient toujours avoir des effets de bord. Exemple :
Plusieurs macros Common Lisp admettent une suite d'expressions et renvoient la valeur de la dernière sans nécessité de progn explicite. On parle de progn implicite (en Anglais : implicit progn). C'est le cas de defun, let, cond, etc.
Il est souvent nécessaire de mémoriser temporairement une valeur, puis d'évaluer des expressions et finalement de renvoyer cette valeur temporaire. Par exemple dans une fonction qui renvoie le sommet d'une pile, puis dépile la pile, on trouve souvent des constructions similaires à celle-ci :
Cette construction est si fréquente que Common Lisp fournit la macro prog1 qui permet d'écrire cela plus simplement :
Comme progn, prog1 prend une séquence d'expressions, cependant prog1 nécessite au moins une expression. Les expressions sont évaluées séquentiellement de la même manière qu'avec progn, mais c'est la valeur de la première expression qui sera la valeur de l'expression prog1 entière.
Il existe également une construction prog2, similaire à prog1, mis à part que c'est la valeur de la deuxième expression qui est renvoyée.
Un autre type de bloc très utile est block, qui correspond à un progn nommé. Le nom permet l'exécution d'une expression return-from permettant de sortir immédiatement du bloc avec une valeur donnée. Exemple :
D'autres types de blocs plus esotériques comme progv, prog et tagbody existent également.
Irene DURAND