AccueilđŸ‡«đŸ‡·Chercher

MĂ©taprogrammation

La mĂ©taprogrammation, nommĂ©e par analogie avec les mĂ©tadonnĂ©es et les mĂ©taclasses, dĂ©signe l'Ă©criture de programmes qui manipulent des donnĂ©es dĂ©crivant elles-mĂȘmes des programmes. Dans le cas particulier oĂč le programme manipule ses propres instructions pendant son exĂ©cution, on parle de programme auto-modifiant.

Elle peut ĂȘtre employĂ©e pour gĂ©nĂ©rer du code interprĂ©tĂ© par un compilateur et donner un rĂ©sultat constant, afin d'Ă©viter un calcul manuel. Il permet Ă©galement de rĂ©duire le temps d'exĂ©cution du programme si le rĂ©sultat constant avait Ă©tĂ© classiquement calculĂ© par le programme comme pour les rĂ©sultats variables.

Cette mĂ©thode ne s'applique pas uniquement aux calculs mais aussi au remplissage de donnĂ©es constantes telles que des tableaux ou des structures plus complexes. Cependant cette technique ne fonctionne que pour des valeurs constantes. En effet, si une donnĂ©e manipulĂ©e par le mĂ©taprogramme est une entrĂ©e du programme, par exemple une saisie de l’utilisateur, elle ne peut pas ĂȘtre connue avant l'exĂ©cution du programme. Il est donc impossible qu'un tel mĂ©taprogramme soit interprĂ©tĂ© par un compilateur. L'optimisation par mĂ©taprogrammation est alors totalement perdue.

La mĂ©taprogrammation ne se limite pas seulement Ă  l'Ă©criture de donnĂ©es contenant un programme destinĂ© au compilateur. Elle peut simplement ĂȘtre la manipulation d'un programme en fonction d'entrĂ©es variables. Par exemple, un programme peut, selon ses entrĂ©es, muter le code d'un mĂ©taprogramme. Ce mĂ©taprogramme peut alors ĂȘtre destinĂ© Ă  une exĂ©cution ultĂ©rieure ou une gĂ©nĂ©ration de code.

Processus

Il existe différentes façons de procéder :

Les deux premiĂšres techniques sont disponibles pour les langages Ă  typage statique. Il s'agit d'une forme puissante mais limitĂ©e de mĂ©ta-programmation. Le principe du gĂ©nĂ©rateur de code revient en effet Ă  construire un compilateur comprenant la sĂ©mantique d'un langage donnĂ©, avec des ajouts. Cette approche n'est donc pas facilement portable. La programmation Ă  base de templates permet de construire des opĂ©rateurs pour des types de donnĂ©es complĂštement hĂ©tĂ©rogĂšnes — c'est utile en C++. Les templates de Common Lisp sont plus gĂ©nĂ©raux. Ces deux techniques ne concernent que la phase de compilation. Certains langages acadĂ©miques (comme MetaOcaml par exemple) fournissent un typage qui garantit que les programmes gĂ©nĂ©rĂ©s par le mĂ©ta-programme sont correctement typĂ©s.

Les langages rĂ©flexifs offrent des moyens d'introspection et de modification en cours d'exĂ©cution, non seulement des valeurs et objets du domaine d'une application mais du comportement du systĂšme (entendre comme le langage + ses bibliothĂšques standards). Les protocoles Ă  mĂ©ta-objets permettent de spĂ©cifier le comportement au niveau des classes elles-mĂȘmes (on y considĂšre les classes, les mĂ©thodes, comme des objets d'un domaine particulier).

Un systÚme de macro-définition (ou macros) permet de réaliser des transformations de source à source : on peut ainsi ajouter de nouveaux opérateurs à un langage sans altérer sa spécification ni modifier le compilateur (contrairement au principe des générateurs de code). Seuls les langages représentés avec des s-expressions offrent un systÚme de macros satisfaisant et utilisable, du fait de la convergence entre la syntaxe abstraite des programmes et leur syntaxe concrÚte.

Certains systĂšmes experts explicitent ou dirigent le fonctionnement de leur moteur d'infĂ©rence par des mĂ©ta-rĂšgles ou mĂ©ta-connaissances qui peuvent ĂȘtre considĂ©rĂ©es comme des mĂ©ta-programmes.

Exemple

Par exemple, pour effectuer le calcul d'une somme finie des nombres entiers inférieurs à 10 (ou toute autre valeur constante), il faut faire le calcul 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, on peut :

  • crĂ©er une fonction qui calcule la somme de i allant de 1 Ă  n, puis donner n = 10 en paramĂštre ;
  • calculer Ă  la main pour utiliser directement le rĂ©sultat : 55 ;
  • faire un mĂ©taprogramme qui calculera la somme lors de la compilation.

Dans le premier cas, on crée une fonction qui permettra au programme de faire le calcul. Cette technique peut paraßtre inutile et faire perdre du temps à l'exécution du programme car tout est constant. Le programme serait plus optimisé si le calcul était déjà fait avant son exécution.

Dans le deuxiĂšme cas, on calcule soi-mĂȘme la valeur et on la met dans le code source du programme. Ceci pose deux inconvĂ©nients :

  • Le calcul peut ĂȘtre faux. Ceci causerait ainsi des erreurs dans les rĂ©sultats fournis par le programme. De plus, il est difficile de dĂ©boguer et retrouver l'origine du problĂšme ;
  • Le calcul peut ĂȘtre long et fastidieux. En effet, sur l'exemple, seulement 10 valeurs sont calculĂ©es, mais une plus grande somme prendrait beaucoup plus de temps. MĂȘme si, sur cet exemple, on peut dĂ©montrer que (suite arithmĂ©tique), il n'existe pas toujours une formule mathĂ©matique simplificatrice, ou alors on n'en connaĂźt pas.

Dans le troisiÚme cas, le calcul est effectué en programmant un programme destiné au compilateur. Celui-ci exécute ce métaprogramme pour le transformer en donnée constante. C'est la méthode la plus optimisée pour les calculateurs humains et informatiques, car le métaprogramme n'est qu'une donnée qui, dans ce cas, est évaluée sans exécuter le programme final.

Voir aussi

Articles connexes

Cet article est issu de wikipedia. Text licence: CC BY-SA 4.0, Des conditions supplĂ©mentaires peuvent s’appliquer aux fichiers multimĂ©dias.