La métaprogrammation fait référence à une variété de façons dont un programme a une connaissance de lui-même ou peut se manipuler.
Dans des langages comme C#, la réflexion est une forme de métaprogrammation puisque le programme peut examiner des informations sur lui-même. Par exemple renvoyer une liste de toutes les propriétés d’un objet.
Dans des langages comme ActionScript, vous pouvez évaluer des fonctions au moment de l’exécution pour créer de nouveaux programmes tels que eval(« x » + i). DoSomething() affecterait un objet appelé x1 lorsque i vaut 1 et x2 lorsque i vaut 2.
Enfin, une autre forme courante de métaprogrammation est lorsque le programme peut se modifier lui-même de manière non triviale. LISP est bien connu pour cela et c’est quelque chose que Paul Graham a défendu il y a environ une décennie. Il faudra que je recherche certains de ses essais spécifiques. Mais l’idée est que le programme change une autre partie du programme en fonction de son état. Cela permet un niveau de flexibilité pour prendre des décisions à l’exécution qui est très difficile dans la plupart des langages populaires d’aujourd’hui.
Il est également intéressant de noter qu’à l’époque du bon vieux temps de la programmation en assembleur direct, les programmes qui se modifiaient eux-mêmes à l’exécution étaient nécessaires et très courants.
Dans l’essai de Paul Graham « What Made Lisp Different »:
De nombreux langages ont quelque chose appelé une macro. Mais les macros Lisp sont uniques. Et croyez-le ou non, ce qu’elles font est lié aux parenthèses. Les concepteurs de Lisp n’ont pas mis toutes ces parenthèses dans le langage juste pour être différents. Pour le programmeur Blub, le code Lisp a l’air bizarre. Mais ces parenthèses sont là pour une raison. Elles sont la preuve extérieure d’une différence fondamentale entre Lisp et les autres langages.
Le code Lisp est fait d’objets de données Lisp. Et pas dans le sens trivial que les fichiers sources contiennent des caractères, et que les chaînes de caractères sont un des types de données supportés par le langage. Le code Lisp, après avoir été lu par l’analyseur syntaxique, est fait de structures de données que vous pouvez parcourir.
Si vous comprenez comment fonctionnent les compilateurs, ce qui se passe réellement n’est pas tant que Lisp a une syntaxe étrange que que Lisp n’a pas de syntaxe. Vous écrivez des programmes dans les arbres d’analyse qui sont générés dans le compilateur lorsque d’autres langues sont analysées. Mais ces arbres d’analyse sont entièrement accessibles à vos programmes. Vous pouvez écrire des programmes qui les manipulent. En Lisp, ces programmes sont appelés des macros. Ce sont des programmes qui écrivent des programmes.
Des programmes qui écrivent des programmes ? Quand voudriez-vous faire ça ? Pas très souvent, si vous pensez en Cobol. Tout le temps, si vous pensez en Lisp. Ce serait commode ici si je pouvais donner un exemple d’une macro puissante, et dire voilà ! qu’en est-il de cela ? Mais si je le faisais, cela ressemblerait à du charabia pour quelqu’un qui ne connaît pas Lisp ; il n’y a pas la place ici pour expliquer tout ce que vous devez savoir pour comprendre ce que cela signifie. Dans Ansi Common Lisp, j’ai essayé de faire avancer les choses aussi vite que possible, et même ainsi, je ne suis pas arrivé aux macros avant la page 160.
Mais je pense pouvoir donner un type d’argument qui pourrait être convaincant. Le code source de l’éditeur Viaweb était probablement composé d’environ 20-25% de macros. Les macros sont plus difficiles à écrire que les fonctions Lisp ordinaires, et il est considéré comme un mauvais style de les utiliser quand elles ne sont pas nécessaires. Ainsi, chaque macro de ce code est là parce qu’elle doit l’être. Cela signifie qu’au moins 20-25% du code de ce programme fait des choses que vous ne pouvez pas facilement faire dans un autre langage. Aussi sceptique que le programmeur de Blub puisse être quant à mes affirmations sur les pouvoirs mystérieux de Lisp, cela devrait le rendre curieux. Nous n’écrivions pas ce code pour notre propre amusement. Nous étions une minuscule startup, programmant aussi fort que nous le pouvions afin de mettre des barrières techniques entre nous et nos concurrents.
Une personne suspicieuse pourrait commencer à se demander s’il n’y avait pas une corrélation ici. Une grande partie de notre code faisait des choses qui sont très difficiles à faire dans d’autres langages. Le logiciel résultant faisait des choses que les logiciels de nos concurrents ne pouvaient pas faire. Peut-être y avait-il une sorte de connexion. Je vous encourage à suivre ce fil. Il y a peut-être plus à ce vieil homme boitillant sur ses béquilles qu’il n’y paraît.