Qu’est-ce que la métaprogrammation?

Je lisais un article sur TheServerSide sur la programmation de Ployglot sur la plate-forme Java . Certains commentaires dans l’article font référence à la métaprogrammation comme à la capacité de générer du code (peut-être à la volée).

Est-ce que la métaprogrammation permet de générer du code à la volée ou est-ce la possibilité d’injecter des méthodes et des atsortingbuts dans des objects existants au moment de l’exécution (comme le permettent certains langages dynamics comme Python, Ruby et Groovy)?

La métaprogrammation se réfère à une variété de manières dont un programme a la connaissance de lui-même ou peut se manipuler.

Dans les langages comme C #, la reflection est une forme de métaprogrammation puisque le programme peut examiner des informations sur lui-même. Par exemple, retourne une liste de toutes les propriétés d’un object.

Dans des langages comme ActionScript, vous pouvez évaluer les fonctions à l’exécution pour créer de nouveaux programmes tels que eval (“x” + i) .DoSomething () affecterait un object appelé x1 lorsque i est égal à 1 et x2 à i.

Enfin, une autre forme courante de métaprogrammation consiste en ce que le programme peut changer lui-même dans des modes non sortingviaux. Le LISP est bien connu pour cela et Paul Graham l’a défendu il y a une dizaine d’années. Je vais devoir chercher certains de ses essais spécifiques. Mais l’idée est que le programme changerait une autre partie du programme en fonction de son état. Cela permet un niveau de flexibilité pour prendre des décisions lors de l’exécution, ce qui est très difficile dans la plupart des langages populaires aujourd’hui.

Il est également intéressant de noter que, dans le bon vieux temps de la programmation en assemblage direct, les programmes qui se modifiaient à l’exécution étaient nécessaires et très courants.

Extrait de l’essai de Paul Graham “What Made Lisp Different” :

Beaucoup de langues ont quelque chose qui s’appelle une macro. Mais les macros Lisp sont uniques. Et croyez-le ou non, ce qu’ils font est lié aux parenthèses. Les concepteurs de Lisp n’ont pas mis toutes les parenthèses dans la langue juste pour être différents. Pour le programmeur Blub, le code Lisp est bizarre. Mais ces parenthèses sont là pour une raison. Ils sont la preuve extérieure d’une différence fondamentale entre Lisp et d’autres langages.

Le code Lisp est constitué d’objects de données Lisp. Et pas au sens banal que les fichiers sources contiennent des caractères et que les chaînes sont l’un des types de données pris en charge par le langage. Le code Lisp, une fois lu par l’parsingur, est constitué de structures de données que vous pouvez parcourir.

Si vous comprenez le fonctionnement des compilateurs, ce qui se passe réellement n’est pas tant que Lisp a une syntaxe étrange, car Lisp n’a pas de syntaxe. Vous écrivez des programmes dans les arbres d’parsing générés dans le compilateur lorsque d’autres langages sont analysés. Mais ces arbres d’parsing sont entièrement accessibles à vos programmes. Vous pouvez écrire des programmes qui les manipulent. En Lisp, ces programmes s’appellent des macros. Ce sont des programmes qui écrivent des programmes.

Des programmes qui écrivent des programmes? Quand voudriez-vous jamais faire ça? Pas très souvent, si vous pensez en Cobol. Tout le temps, si vous pensez en Lisp. Ce serait pratique ici si je pouvais donner un exemple de macro puissante, et dire là! que diriez-vous de ça? Mais si je le faisais, cela ressemblerait simplement à du charabia à quelqu’un qui ne connaissait pas Lisp; il n’y a pas de 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, malgré cela, je ne suis pas arrivé aux macros avant la page 160.

Mais je pense que je peux donner une sorte d’argument qui pourrait être convaincant. Le code source de l’éditeur Viaweb était probablement d’environ 20-25% de macros. Les macros sont plus difficiles à écrire que les fonctions Lisp ordinaires, et elles sont considérées comme de mauvais style pour les utiliser lorsqu’elles ne sont pas nécessaires. Donc, chaque macro dans ce code est là car elle doit l’être. Cela signifie qu’au moins 20-25% du code de ce programme fait des choses que vous ne pouvez pas faire facilement dans une autre langue. Si sceptique que le programmeur Blub puisse être à propos de mes revendications pour les pouvoirs mystérieux de Lisp, cela devrait le rendre curieux. Nous n’écrivions pas ce code pour notre propre amusement. Nous étions une petite startup, programmant autant que possible afin de mettre des barrières techniques entre nous et nos concurrents.

Une personne suspecte pourrait commencer à se demander s’il y avait une corrélation ici. Une grande partie de notre code consistait à faire des choses très difficiles à faire dans d’autres langues. Le logiciel qui en résultait faisait des choses que les logiciels de nos concurrents ne pouvaient pas faire. Peut-être qu’il y avait une sorte de connexion. Je vous encourage à suivre ce fil. Il y a peut-être plus à ce vieil homme qui traîne sur ses béquilles que ce que l’on voit.

Eh bien, la métaprogrammation est juste la programmation, mais fondamentalement, “écrire du code qui écrit du code” .

La capacité que vous mentionnez, lorsqu’un programme peut observer et modifier sa propre structure et son comportement, s’appelle la reflection et est un type de métaprogrammation.

Langages typés dynamicment, ont de puissantes fonctionnalités de reflection à l’exécution, rendues possibles par la nature interprétée de ces langages …

Les langages typés statiques ont également de puissantes techniques de métaprogrammation, par exemple la métaprogrammation des modèles C ++ …

Bonne question Je suis vraiment désolé de voir qu’aucune des réponses ne répond actuellement vraiment à votre question. Je peux peut-être aider …

La définition de métaprogrammation est très simple: cela signifie que les programmes manipulent des programmes.

Votre réponse acceptée dit des programmes qui se manipulent eux-mêmes. Ce sont en effet des métaprogrammes mais ils constituent un sous-ensemble de tous les métaprogrammes.

Tout:

  • Parsers
  • Langues spécifiques au domaine (DSL)
  • Langages spécifiques au domaine incorporé (EDSL)
  • Compilateurs
  • Des interprètes
  • Réécrivains à terme
  • Théorème prouve

sont des métaprogrammes. Le compilateur GCC est donc un métaprogramme, l’ interpréteur CPython est un métaprogramme, le système d’algèbre informatique Mathematica est un métaprogramme, le prouveur du théorème Coq est un métaprogramme, etc.

D’autres réponses ont affirmé que les métaprogrammes sont des programmes qui génèrent d’autres programmes. Ce sont en effet des métaprogrammes mais, encore une fois, ils constituent un sous-ensemble de tous les métaprogrammes. La bibliothèque de transformée de Fourier la plus rapide dans l’Ouest (FFTW) est un exemple d’un tel métaprogramme. Le code source est principalement écrit en OCaml et génère des bits de code C (appelés codelets) qui sont combinés pour créer des routines Fast Transform de Fourier hautes performances optimisées pour des machines spécifiques. Cette bibliothèque est en fait utilisée pour fournir les routines FFT dans Matlab. Les gens écrivent des programmes pour générer des méthodes numériques depuis des décennies, depuis les débuts du FORTRAN .

Le langage de programmation LISt (LISt) était le premier langage de programmation intégré au support de métaprogrammation à la fin des années 1950. LISP 1.5 incluait un certain nombre de fonctionnalités qui facilitaient la métaprogrammation. Premièrement, le type de données de base de LISP est constitué de listes nestedes, c’est-à-dire des arbres comme (a (bc) d) , ce qui signifie que tout code LISP peut être exprimé nativement en tant que structure de données. C’est ce qu’on appelle l’homoiconicité. Deuxièmement, le code LISP peut être converti en données facilement en utilisant QUOTE. Par exemple (+ 1 2 3) ajoute 1 + 2 + 3 et (QUOTE (+ 1 2 3)) crée une expression qui ajoute 1 + 2 + 3 lors de l’évaluation. Troisièmement, LISP a fourni un évaluateur méta-circulaire qui vous permet d’utiliser l’interpréteur ou le compilateur hôte pour évaluer le code LISP au moment de l’exécution, y compris le code LISP généré au moment de l’exécution. Les descendants du LISP incluent Scheme et Clojure . Dans tous ces langages, la métaprogrammation se présente le plus souvent sous la forme de programmes qui se modifient eux-mêmes, en utilisant généralement des macros.

Dans les années 1970, Robin Milner a développé un MetaLanguage (ML) qui a évolué vers la famille ML de langages de programmation qui inclut Standard ML et OCaml et a fortement influencé Haskell et F # . Ces langages facilitent l’expression d’autres langues. Dans ces langues, les métaprogrammes se présentent le plus souvent sous la forme de lexers, d’parsingurs, d’interprètes et de compilateurs.

En 1994, Erwin Unruh a découvert que le système de template C ++ était complet et pouvait être utilisé pour exécuter des programmes arbitraires au moment de la compilation . La métaprogrammation de modèles C ++ a apporté la métaprogrammation aux masses non lavées qui (ab) l’ont utilisée pour de nombreuses choses différentes, y compris la génération de méthodes numériques dans la bibliothèque Blitz ++ .

Ceci est juste mon opinion personnelle, qui est probablement la définition la plus libérale de la métaprogrammation.

Je pense que cela comprend:

  1. Comstackr la génération de code ou la génération de code d’exécution (ou les deux)
  2. Pensée Orientée Aspect ou Programmation Orientée Aspect
  3. Pensée sèche

Je pense que vous pouvez y arriver en utilisant l’un de ceux-ci et en combinaison:

  1. Réflexion
  2. DSL (Domain Specific Languages)
  3. Atsortingbuts (.NET) ou Annotations (Java)
  4. Génériques (.NET / Java)
  5. Modèles (C ++)
  6. method_missing (Ruby)
  7. fermetures / fonctions de première classe / delegates
  8. AOP – Programmation par aspects

La métaprogrammation consiste à écrire un programme qui produit un autre programme. C’est quelque chose dans lequel les langages comme Lisp sont vraiment bons. Il est beaucoup plus facile de le faire dans un langage qui prend en charge les macros réelles (pas les macros C ++, mais plutôt celles qui peuvent manipuler le code qu’elles produisent) comme Ruby, Lisp, Scheme, etc.

Une des implémentations consiste à créer un “langage spécifique au domaine” qui est un moyen d’améliorer un langage de programmation pour accomplir une tâche spécifique. Il peut être incroyablement puissant s’il est effectué correctement. Ruby on Rails est un bon exemple de ce type de programmation.

Si vous souhaitez explorer cette méthode, consultez la structure et l’interprétation des programmes informatiques, qui est l’un des ouvrages de référence.

La métaprogrammation est l’écriture de programmes informatiques qui écrivent ou manipulent d’autres programmes (ou eux-mêmes) en tant que leurs données, ou qui effectuent une partie du travail à l’exécution qui serait effectuée au moment de la compilation. Dans de nombreux cas, cela permet aux programmeurs de faire plus dans le même laps de temps qu’ils n’auraient besoin pour écrire tout le code manuellement, ou cela donne aux programmes une plus grande flexibilité pour gérer efficacement de nouvelles situations sans recompilation. ( Source .)

Fondamentalement, c’est l’écriture de code qui génère plus de code, ce qui est exécuté pour atteindre un objective. Cela se fait généralement dans la même langue (en utilisant javascript pour créer une chaîne javascript, puis l’ eval ) ou pour émettre une autre langue (en utilisant .NET pour créer un fichier batch Windows).

Wikipédia a un bon article sur le sujet. Il n’est pas nécessaire de faire des modifications à l’exécution pour que quelque chose soit qualifié de métaprogrammation. Par exemple, de nombreuses personnes utilisent des modèles C ++ pour effectuer une métaprogrammation au moment de la compilation.