189 votes

Qu'est-ce que la métaprogrammation ?

J'ai lu un article sur TheServerSide concernant la programmation des ployglots sur la plate-forme Java . Certains commentaires de l'article font référence à la métaprogrammation comme à la capacité de générer du code (peut-être à la volée).

La métaprogrammation est-elle la capacité de générer du code à la volée ou la capacité d'injecter des méthodes et des attributs dans des objets existants au moment de l'exécution (comme le permettent certains langages dynamiques tels que Python, Ruby et Groovy).

139voto

DavGarcia Points 9322

La métaprogrammation fait référence aux différentes façons dont un programme a connaissance de lui-même ou peut se manipuler.

Dans des langages comme le C#, la réflexion est une forme de métaprogrammation puisque le programme peut examiner des informations sur lui-même. Par exemple, il peut retourner 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 est égal à 1 et x2 lorsque i est égal à 2.

Enfin, une autre forme courante de métaprogrammation est celle où le programme peut se modifier lui-même de manière non triviale. LISP est bien connu pour cela et c'est une chose dont Paul Graham s'est fait le champion il y a une dizaine d'années. Il faudra que je recherche certains de ses essais spécifiques. Mais l'idée est que le programme modifie une autre partie du programme en fonction de son état. Cela permet un niveau de flexibilité pour prendre des décisions au moment de l'exécution, ce qui est très difficile dans la plupart des langages populaires aujourd'hui.

Il convient également de noter qu'à l'époque de la programmation en langage assembleur, les programmes qui se modifiaient au moment de l'exécution étaient nécessaires et très courants.

Extrait de l'essai de Paul Graham "Ce qui a fait la différence de Lisp :

De nombreuses langues ont macro. Mais les macros Lisp sont uniques. Et je croyez-le ou non, ce qu'elles font est lié aux parenthèses. Le concepteurs de Lisp n'ont pas mis toutes ces parenthèses dans le langage juste pour être 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 constitué de données Lisp Lisp. Et pas dans le sens trivial que les fichiers sources contiennent des et que les chaînes de caractères sont l'un des types de données pris en charge par le langage. Le code Lisp, après avoir été lu par l'analyseur syntaxique, est constitué de structures de données. par l'analyseur, est constitué de structures de données que vous pouvez parcourir.

Si vous comprenez comment ce qui se passe en réalité n'est pas tellement que Lisp a une syntaxe étrange, mais plutôt que Lisp n'a pas de syntaxe. Vous écrivez des programmes dans les arbres d'analyse générés dans le compilateur lorsque d'autres d'autres langages sont analysés. Mais ces arbres sont entièrement accessibles à votre programmes. Vous pouvez écrire des programmes qui les manipuler. En Lisp, ces programmes sont appelés macros. Ils sont des des programmes qui écrivent des programmes.

Des programmes qui écrivent des programmes ? Quand voudriez-vous faire cela ? Pas de très souvent, si vous pensez en Cobol. Tous les tout le temps, si vous pensez en Lisp. Il serait serait pratique ici si je pouvais donner un exemple de macro puissante, et dire : "Voilà, qu'en pensez-vous ? Mais si je le faisais, cela ressemblerait à du charabia pour quelqu'un qui ne connaîtrait pas le langage Lisp ; il n'y a pas assez de place ici pour expliquer tout ce qu'il faut savoir pour comprendre comprendre ce que cela signifie. En A Common Lisp J'ai essayé de faire bouger les choses aussi vite que possible, et même ainsi je n'ai pas abordé les macros avant la page 160.

Mais je pense que je peux donner un coup de pouce. argument qui pourrait être convaincant. Le code source de l'éditeur Viaweb était était probablement composé de 20 à 25 % de macros. Les macros sont plus difficiles à écrire que les fonctions Lisp ordinaires, et les [ ] nécessaires. Ainsi, chaque macro de ce code est là parce qu'elle doit l'être. Ce qui signifie qu'au moins 20-25% du code du code de ce programme fait des choses des choses que l'on ne peut pas faire facilement dans autre langage. Aussi sceptique que soit le programmeur de programmeur Blub soit sceptique quant à mes mes affirmations sur les pouvoirs mystérieux de Lisp, cela devrait le rendre curieux. Nous n'avons pas écrit ce code pour notre pour nous amuser. Nous étions une minuscule start-up, programmant aussi fort que nous le pouvions afin de mettre des barrières techniques entre nous et nos concurrents.

Une personne suspecte se demander s'il n'y a pas une corrélation ici. Une grande partie de notre code était faisait des choses qui sont très difficiles à faire dans d'autres langages. Le logiciel qui en résulte logiciel résultant faisait des choses que les concurrents ne pouvaient pas faire. Il y avait peut-être qu'il y avait une sorte de lien. Je vous encourage à suivre ce fil. Il y a peut-être plus à ce vieil homme qui clopine sur ses béquilles.

104voto

Jon Harrop Points 26951

Excellente question. Je suis désolé de constater qu'aucune des réponses actuelles ne répond vraiment à votre question. Je peux peut-être vous aider...

La définition de la métaprogrammation est très simple : il s'agit de programmes qui manipulent des programmes.

La réponse que vous avez acceptée est : "des programmes qui se manipulent eux-mêmes". Il s'agit bien de métaprogrammes, mais ils constituent un sous-ensemble de tous les métaprogrammes.

Tous :

  • Analyseurs
  • Langages spécifiques à un domaine (DSL)
  • Langages spécifiques aux domaines intégrés (EDSL)
  • Compilateurs
  • Interprètes
  • Réécriture de termes
  • Les prouveurs de théorèmes

sont des métaprogrammes. Ainsi, les Compilateur GCC est un métaprogramme, le Interprète CPython est un métaprogramme, le Système de calcul formel Mathematica est un métaprogramme, le Producteur de théorèmes 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. Il s'agit bien de métaprogrammes mais, là encore, il s'agit d'un sous-ensemble de tous les métaprogrammes. Les La transformation de Fourier la plus rapide de l'Occident (FFTW) est un exemple de ce type de métaprogramme. Le code source est écrit principalement en OCaml et il génère des morceaux de code C (appelés codelets) qui sont combinés pour créer des systèmes d'information performants. Transformée de Fourier rapide des routines optimisées pour des machines spécifiques. Cette bibliothèque est en fait utilisée pour fournir les routines FFT dans Matlab. Cela fait des décennies que l'on écrit des programmes pour générer des méthodes numériques, depuis les premiers jours du FORTRAN .

Le premier langage de programmation à avoir intégré la métaprogrammation est le langage LISt Processor (LISP), qui date de la fin des années 1950. LISP 1.5 comportait un certain nombre de fonctionnalités qui facilitaient la métaprogrammation. Tout d'abord, le type de données central de LISP est constitué de listes imbriquées, c'est-à-dire d'arbres tels que (a (b c) d) ce qui signifie que tout code LISP peut être exprimé nativement comme une structure de données. C'est ce qu'on appelle l'homoiconicité. Deuxièmement, le code LISP peut être facilement converti en données à l'aide de QUOTE. Par exemple, le code LISP peut être converti en données facilement à l'aide de QUOTE. (+ 1 2 3) ajoute 1+2+3 et (QUOTE (+ 1 2 3)) crée une expression qui additionne 1+2+3 lorsqu'elle est évaluée. Troisièmement, LISP fournit 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 de LISP comprennent Régime y Clojure . Dans tous ces langages, la métaprogrammation se manifeste le plus souvent sous la forme de programmes qui se modifient eux-mêmes, généralement à l'aide de macros.

Dans les années 1970, Robin Milner a mis au point un MetaLanguage (ML) qui a évolué vers la famille ML de langages de programmation qui comprend Standard ML y OCaml et a fortement influencé Haskell y F# . Ces langages facilitent l'expression d'autres langages. Dans ces langages, les métaprogrammes se présentent le plus souvent sous la forme de lexiques, d'analyseurs syntaxiques, d'interprètes et de compilateurs.

En 1994, Erwin Unruh a découvert que le système de modèles C++ était complet au sens de Turing et qu'il pouvait être utilisé pour exécuter des programmes arbitraires au moment de la compilation. . La métaprogrammation des modèles C++ a mis la métaprogrammation à la portée de tous, qui l'ont (ab)utilisée pour de nombreuses choses différentes, y compris la génération de méthodes numériques dans le système de gestion de l'information. Bibliothèque Blitz .

43voto

CMS Points 315406

La métaprogrammation n'est rien d'autre que de la programmation, mais c'est essentiellement "é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 réflexion et c'est un type de métaprogrammation.

Les langages typés dynamiquement disposent de puissantes fonctions de réflexion à l'exécution, rendues possibles par la nature interprétée de ces langages...

Les langages typés statiques disposent également de puissantes techniques de métaprogrammation, par exemple le langage C++. métaprogrammation par modèles ...

18voto

BuddyJoe Points 15690

Ce n'est que mon opinion personnelle, qui est probablement la définition la plus libérale de la métaprogrammation.

Je pense qu'il comprend :

  1. Génération du code de compilation ou génération du code d'exécution (ou les deux)
  2. Pensée orientée vers les aspects ou programmation orientée vers les aspects
  3. SEC Réflexion

Je pense qu'il est possible d'y parvenir en utilisant l'un ou l'autre de ces éléments et en les combinant :

  1. Réflexion
  2. DSLs (Domain Specific Languages)
  3. Attributs (.NET) ou Annotations (Java)
  4. Génériques (.NET/Java)
  5. Modèles (C++)
  6. méthode_manquante (Ruby)
  7. fermetures / fonctions de première classe / délégués
  8. AOP - Programmation orientée aspects

8voto

EndangeredMassa Points 9532

La métaprogrammation est l'écriture de programmes informatiques qui écrivent ou manipulent d'autres programmes (ou eux-mêmes) en tant que données, ou qui effectuent au moment de l'exécution une partie du travail qui serait autrement effectué au moment de la compilation. Dans de nombreux cas, cela permet aux programmeurs d'en faire plus dans le même laps de temps que celui qu'il leur faudrait 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, il s'agit d'écrire du code qui produit d'autres codes, qui sont exécutés pour atteindre un certain objectif. Cela se fait généralement dans le même langage (en utilisant javascript pour créer une chaîne de caractères javascript, puis eval ) ou d'émettre un autre langage (en utilisant .NET pour créer un fichier batch Windows).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X