Macros
Clojure possède un système de macros programmatiques permettant d'étendre le compilateur par le code utilisateur. Les macros peuvent servir à définir des constructions syntaxiques qui, dans d'autres langages, nécessiteraient des types primitifs ou une prise en charge native. De nombreuses constructions fondamentales de Clojure ne sont pas, en réalité, des types primitifs, mais des macros classiques.
Certaines macros produisent de simples combinaisons de formes primitives. Par exemple, la combinaison de `if` et `do` donne :
- user=> (macroexpand '(when (pos? a) (println "positive") (/ b a)))
- (if (pos? a) (do (println "positive") (/ b a)))
D'autres macros réorganisent les formes de manière utile, comme la macro ->, insérant récursivement chaque expression comme premier argument de l'expression suivante :
- user=> (-> {} (assoc :a 1) (assoc :b 2))
- {:b 2, :a 1}
- user=> (macroexpand '(-> {} (assoc :a 1) (assoc :b 2)))
- (assoc (assoc {} :a 1) :b 2)
Variables spéciales
Deux variables spéciales sont disponibles dans defmacro pour des utilisations plus avancées :
| Variable | Description |
|---|---|
| &form | Le formulaire (sous forme de données) invoqué. |
| &env | Une table de correspondance des liaisons locales au point d'expansion de la macro. Cette table associe les symboles aux objets contenant les informations du compilateur relatives à cette liaison. |
Toutes les macros suivantes sont documentées sur la page API. De nombreux points sont également abordés sur les pages thématiques, comme indiqué :
| Catégorie | Macros |
|---|---|
| Création de macros | defmacro, definline, macroexpand-1, macroexpand |
| Branchage | and, or, when, when-not, when-let, when-first, if-not, if-let, cond, condp |
| Boucles (voir aussi Séquences) | for, doseq, dotimes, while |
| Manipulation des variables (voir aussi Variables et Environnement) | ns, declare, defn, defmacro, definline, defmethod, defmulti, defn-, defonce, defstruct |
| Modification de l'organisation du code | .. doto -> |
| Portées dynamiques (voir aussi Variables et Environnement) | binding, locking, time, with-in-str, with-local-vars, with-open, with-out-str, with-precision |
| Création d'objets paresseux (voir aussi Séquences) | lazy-seq, lazy-cat, delay |
| Macros d'interopérabilité Java | .. amap, areduce, gen-class, gen-interface, proxy, proxy-super, memfn |
| Documentation du code | assert, comment, doc |
| Transactions | dosync io! |
Certaines formes spéciales sont implémentées sous forme de macros, principalement pour permettre la déstructuration : fn let loop