On peut voir la programmation comme la construction systématique d'abstractions. Il y a trois types d'abstractions possibles :
Seules l'abstraction de données et l'abstraction de contrôle existent dans les langages traditionnels. L'abstraction syntaxique se fait en Common Lisp avec des macros. Une macro est similaire à une fonction, mais au lieu de calculer une valeur à partir de valeurs données en arguments, une macro calcule un bout de programme à partir de bouts de programmes passés en arguments. Une macro est donc une fonction qui transforme du code.
Une grande partie des fonctionnalités de Common Lisp sont implémentées par des macros dont le code généré n'utilise que des constructions plus simples. De cette manière, Common Lisp est contruit en couches d'abstraction qui augmentent les constructions syntaxiques existantes. C'est comme si le langage C permettait la création de nouveaux types de boucles et d'instructions.
Grâce aux macros, la programmation en Common Lisp consiste en grande partie à étendre le langage pour exprimer des idiomes du domaine de l'application. De fait, Common Lisp se transforme en un langage dédié à une classe d'applications, la partie spécifique à la classe d'applications devenant un langage enchâssé. Ceci simplifie ensuite la programmation de l'application et surtout sa maintenance.