75 votes

A quoi sert la métaprogrammation ?

J'ai lu :

et je confesse une certaine confusion quant à l'objectif derrière la métaprogrammation/génération de code.

Quelqu'un a-t-il un exemple concret d'utilisation de la métaprogrammation/génération de code ? Il serait encore mieux d'expliquer pourquoi cette méthode est meilleure qu'une autre.

modifier : Serait Chardon être considéré comme de la métaprogrammation ?

1 votes

Votre deuxième lien semble assez clair, quelle est votre compréhension des deux concepts, pour voir s'il y a une confusion fondamentale de votre part, sinon votre question est trop large et subjective IMO.

1 votes

Ma question est d'ordre pratique : pourquoi la métaprogrammation est-elle meilleure que, par exemple, l'écriture de quelques éléments de requêtes SQL paramétrées et leur assemblage sur la base de certaines conditions ? Ou es c'est de la métaprogrammation ? (Je ne pensez à mais c'est pour cela que je pose la question - Est-ce différent et pourquoi est-ce mieux ?).

1 votes

Parce que parfois, vous ne savez même pas à l'avance quelle table vous allez interroger ou quelles colonnes vous allez retourner (cela dépend peut-être d'une combinaison d'entrées utilisateur, trop difficile de précalculer toutes les possibilités à l'avance), vous utilisez donc le SQL dynamique (qui pourrait peut-être être considéré comme une forme de métaprogrammation).

117voto

Benoît Points 10901

Imaginez un type qui construit des voitures. Dis que c'est la même chose que d'utiliser un ordinateur.
A un moment donné, il réalise qu'il fait toujours la même chose, plus ou moins.
Alors il construit des usines pour construire des voitures, et c'est bien mieux. Il programme maintenant !
Néanmoins, une fois encore, à un moment donné, il se rend compte qu'il fait toujours la même chose, dans une certaine mesure.
Maintenant il décide de construire des usines qui construisent des usines qui construisent des voitures. C'est de la métaprogrammation.

La métaprogrammation est immensément puissante, mais une faille dans le système transforme tous les avantages en difficultés monstres. Alors maîtrisez-la et utilisez-la... Ou restez à l'écart !

6 votes

C'est une bonne réponse, mais elle montre la chose que je trouve la plus ennuyeuse dans la métaprogrammation. Quand est-ce que ça s'arrête ? Qu'est-ce qui nous empêche d'avoir des usines qui construisent des usines qui construisent des moutons qui construisent des usines qui construisent des voitures ?

5 votes

@XQLRSZ De la même manière que vous savez quand vous devez arrêter d'écrire du code : quand il ne vous facilite plus la vie. À moins que vous ne fassiez quelque chose encore et encore, il n'y a aucune raison de l'extraire dans un morceau de code.

2 votes

Dans certains environnements, il nunca extrémités. Voir cet exposé de Nada Amin, "Les logiciels devraient se manger eux-mêmes". youtube.com/watch?v=SrKj4hYic5A

21voto

Ira Baxter Points 48153

Je vois le métaprogamme comme "des programmes qui écrivent (ou modifient) d'autres programmes". (Une autre réponse disait "des usines qui fabriquent des usines", belle analogie).

Les gens trouvent toutes sortes d'utilisations pour cela : personnalisation des applications, génération de code passe-partout, l'optimisation d'un programme pour des circonstances particulières, l'implémentation de DSL, l'insertion de code pour traiter des problèmes de conception orthogonaux ("aspects") ...

Ce qui est remarquable, c'est le nombre de mécanismes différents qui ont été inventés pour y parvenir au coup par coup : modèles de texte, macros, conditionnels de préprocesseur, génériques, modèles C++, aspects, réflexion,... Et généralement, certains de ces mécanismes sont intégrés dans certains langages, et d'autres mécanismes dans d'autres langages. dans d'autres langages, et la plupart des langages n'ont aucun support de métaprogrammation. Cette distribution éparpillée des capacités signifie que vous pouvez être en mesure de faire certains types de métaprogrammation dans certains langages. de métaprogrammation dans un langage, avec des limitations, et ne pas pouvoir le faire dans un autre. C'est exaspérant :-}

Une observation que j'ai suivie à la lettre est que l'on peut construire des produits génériques. de métaprogrammation générique qui fonctionne avec tout sous forme de transformations du programme . Une transformation de programme est un modèle paramétré : "si vous voyez ce remplacez-la par que syntaxe".

Une transformation en soi n'est généralement pas impressionnante, mais des douzaines ou des centaines de transformations peuvent faire de l'argent. des changements spectaculaires dans le code. Parce que les transformations de programmes (sophistiquées) peuvent simuler une machine de Turing, elles peuvent effectuer des modifications arbitraires du code, y compris toutes ces techniques ponctuelles que vous trouvez éparpillées.

Un outil qui accepte des définitions de langage. des transformations spécifiques au langage et qui génère un autre pour appliquer ces transformations est un méta -outil de métaprogrammation : un programme pour écrire des "programmes qui écrivent des programmes".

L'intérêt est que vous pouvez appliquer un tel outil pour effectuer des changements très variés à un code arbitraire. Et, vous n'avez pas besoin du comité de conception du langage pour réaliser que vous que vous voulez un type particulier de support de métaprogrammation, et se dépêcher de le fournir pour que vous puissiez continuer votre travail aujourd'hui.

Une leçon intéressante est que de telles machines nécessitent une analyse de programme solide (symbole (tables de symboles, analyse des flux de contrôle et de données, etc.) ) pour l'aider à se concentrer sur l'endroit où se trouvent les problèmes dans le code, afin que la métaprogrammation ) pour l'aider à se concentrer sur l'endroit où se trouvent les problèmes dans le code, afin que la machine de métaprogrammation puisse faire quelque chose à cet endroit (un exemple très faible de ceci est les spécifications par points dans les aspects, qui disent "faites des changements aux endroits qui ressemblent à ceci").

Le PO a demandé des exemples spécifiques d'application de la métaprogrammation. Nous avons utilisé notre outil de métaprogrammation "méta" ( Boîte à outils de réingénierie des logiciels DMS ) pour réaliser les activités suivantes sur grand site les bases de code automatiquement :

  • Migration des langues
  • Mise en œuvre de la couverture des tests et des profileurs
  • Mise en œuvre de la détection des clones
  • Réingénierie massive de l'architecture
  • Génération de codes pour le contrôle en usine
  • SOAisation des contrôleurs de réseau embarqués
  • Extraction d'architecture pour les logiciels de l'ordinateur central
  • Génération d'instructions SIMD vectorielles à partir de calculs de tableaux
  • Rétro-ingénierie du code jusqu'aux concepts

dans de nombreux langages, notamment Java, C#, C++, PHP, ...

L'OP a également demandé, "Pourquoi était-ce mieux que l'alternative ?" La réponse a trait à l'échelle, au temps et à la précision.

Pour les grandes applications, la simple taille de la base de code signifie que vous n'avez pas les ressources ou le temps de faire de telles analyses ou modifications à la main. ou le temps pour effectuer de telles analyses ou modifications à la main.

Pour les tâches de génération de code ou d'optimisation, vous pouvez faire ce qui suit à la main, mais les outils peuvent le faire beaucoup plus rapidement et avec plus de précision.

En substance, ces outils font ce que les êtres humains ne peuvent tout simplement pas faire.

Il convient de noter que les outils ne sont pas créatifs. humains pour déterminer ce qu'ils doivent faire, c'est-à-dire décider de la nature de la quelle est la tâche à accomplir (voir la liste d'exemples ci-dessus) et déterminer comment définir les analyses/transformations pour obtenir cet effet. Vous avez toujours besoin méta -programmeurs. Cependant, lorsqu'un méta-programmeur arme un tel outil avec les bonnes connaissances, le code résultant peut sembler être construit par un codeur expert, créatif et incroyablement rapide.

5voto

Georg Fritzsche Points 59185

C'est la métaprogrammation qui m'a le plus servi pour faire le lien entre différentes API.

Un exemple concret est celui de FireBreaths. JSAPIAuto 1 qui facilite l'écriture de classes C++ exposées à JavaScript. En fournissant une facilité d'enregistrement pour les fonctions qui doivent être exposées, les types d'arguments peuvent être inspectés et à partir de ce code d'adaptation généré au moment de la compilation qui convertit les types de script-API en types natifs C++ et vice-versa, même en supportant directement map , vector etc.

À titre d'exemple simple, considérons une exposition add(a, b) qui utilise certains types d'API de script :

ScriptVariant add(const std::vector<ScriptVariant>& values) {
    // have to check argument count
    if(values.size() != 2)
        throw script_error("wrong number of arguments");

    try {
        // have to convert from scripting-API types
        long a = values[0].convert_cast<long>();
        long b = values[0].convert_cast<long>();
        return a+b; // potentially need to convert back too
    } catch(ScriptVariant::bad_cast& e) {
        // need to handle conversion failure
        throw script_error("conversion failed :(");
    }
}

La logique réelle enfouie là-dedans n'est qu'une ligne, que les contrôles et les conversions sont ennuyeux et redondants. Avec la facilité d'enregistrement mentionnée précédemment (par exemple dans le constructeur) :

registerMethod("add", make_method(this, &MyClass::add));

on peut maintenant l'écrire simplement comme suit :

long add(long a, long b) {
    return a+b;
}

... et le framework se charge de générer le code nécessaire pour vous.

1 : Bien que je ferais une mise en oeuvre un peu... plus propre... si je devais tout recommencer.

3voto

Mon exemple concret récent (6 derniers mois) de génération de code :

  1. J'ai un script SQL Plus qui génère puis exécute d'autres script SQL Plus. Le script généré exécute des requêtes contre certaines tables qui ont des champs d'horodatage, et lorsque j'ai conçu le script, il était impossible de savoir quelle fenêtre de temps sélectionner. Donc, le script principal fait son travail, et détermine quelles plages de temps doivent être dans les script secondaires. Ensuite, il génère les sous-scripts en écrivant leur code dans le fichier (et en substituant des caractères de substitution aux heures réelles de début et de fin). Enfin, il exécute le(s) sous-script(s). J'ai utilisé cette astuce pour quelques situations maintenant (bien que souvent plus compliquées que celle-ci) où la structure des sous-étapes dépend des résultats des étapes précédentes.

  2. J'ai eu une fois une feuille de calcul qui mettait en correspondance les éléments d'un XSD avec les colonnes d'une table dans une base de données. Il était possible de générer des extraits XSL et des requêtes complètes à partir de la feuille de calcul en utilisant des macros et VBA. Ces extraits et ces requêtes étaient copiés et collés (en grande partie tels quels, sans aucune modification nécessaire) dans le système qui les exécutait et traitait les résultats. Ce n'est pas une belle solution, mais elle a certainement rendu un travail très fastidieux beaucoup moins fastidieux, et le code qui en a résulté était probablement beaucoup plus cohérent que si j'avais passé une semaine ou deux à tout écrire à la main.

SO liste d'exemples de métaprogrammation : Quels sont les exemples les plus cool de métaprogrammation que vous avez vus en C++ ?

2voto

Klaim Points 24511

Les bibliothèques/codes basés sur la métaprogrammation aident à écrire un code simple et directement explicite qui générera pour vous un code détaillé de mise en œuvre, en fonction des paramètres utilisés.

Boost est rempli de bibliothèques (C++) qui démontrent ce qui peut être réalisé avec la métaprogrammation. Voici quelques exemples intéressants (et peut-être difficiles à comprendre) Proto qui permettent la mise en œuvre de DSL , Esprit qui permettent d'écrire un compilateur en utilisant EBNF directement à l'intérieur du code, et de nombreuses autres bibliothèques de soufflage.

3 votes

L'exemple de génération de code correspondant est le programme GNU flex y bison outils. Comme Spirit, il est utilisé pour créer des analyseurs lexicaux et des analyseurs syntaxiques. Cependant, ils ont leur propre langage qui n'est pas C ou C++, doivent s'exécuter en tant qu'étape séparée, et leur sortie doit être compilée par un compilateur C ou C++. Ceci illustre la différence fondamentale entre les générateurs de code et la métaprogrammation : Les générateurs de code font leur travail en tant qu'étape de "prétraitement" séparée, dont le résultat est ensuite compilé, tandis que la métaprogrammation est simplement compilée en code objet en une seule étape, tout comme le reste du code.

0 votes

Je ne pense pas que la "métaprogrammation" par rapport à la "génération de code" soit "est-ce que le compilateur de code source à objet le fait" ou "est-ce que cela est fait dans mon langage de programmation principal". Tout ce qui compte, c'est que le code que j'écris manuellement soit converti en quelque chose qui fonctionne. Le "compilateur" peut utilement faire de la métaprogrammation (c'est-à-dire suivre les directives de métaprogrammation que j'ai écrites) à différents stades, précoce, moyen, tardif. Ce qui compte, c'est que la métaprogrammation consiste à manipuler le code que j'ai écrit, en utilisant du code supplémentaire que j'ai écrit, pour produire le code final qui s'exécute. Oui, cela inclut les générateurs de code IMHO.

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