Question

C ++ est probablement le langage le plus populaire pour les métaprogrammation statique et Java ne le prend pas en charge .

Existe-t-il d'autres langages que C ++ qui prennent en charge la programmation générative (programmes créant des programmes)?

Était-ce utile?

La solution

L’alternative à la méta-programmation de style modèle est le style macro que vous voyez dans diverses implémentations de Lisp. Je suggère de télécharger On Lisp de Paul Graham et de jeter un coup d'œil sur Clojure si vous êtes intéressé par un Lisp avec des macros exécutées sur la machine virtuelle.

Les macros en Lisp sont beaucoup plus puissants que le style C / C ++ et constituent un langage à part entière - ils sont conçus pour la méta-programmation.

Autres conseils

laissez-moi énumérer quelques détails importants sur le fonctionnement de la métaprogrammation dans lisp (ou schéma , ou ardoise , ou choisissez votre langue "dynamique" préférée:

  • lors de la métaprogrammation rapide, vous ne devez pas gérer deux langues . le code de niveau méta est écrit dans le même langage que le code de niveau d'objet qu'il génère. La métaprogrammation ne se limite pas à deux niveaux et est également plus facile pour le cerveau.
  • dans lisp, vous avez le compilateur disponible au moment de l'exécution . En fait, la distinction entre compilation et exécution semble très artificielle et dépend beaucoup de l'endroit où vous placez votre point de vue. dans lisp avec un simple appel de fonction, vous pouvez compiler des fonctions en instructions machine que vous pourrez utiliser comme objets de première classe; c’est-à-dire qu’il peut s’agir de fonctions non nommées que vous pouvez conserver dans une variable locale, une hashtable globale, etc ...
  • Les
  • macros dans lisp sont très simples: un tas de fonctions bourrées dans une table de hachage et données au compilateur. pour chaque forme que le compilateur est sur le point de compiler, il consulte cette hashtable. si elle trouve une fonction, elle l'appelle au moment de la compilation avec le formulaire d'origine et à la place du formulaire d'origine, elle compile le formulaire renvoyé par cette fonction. (modulo des détails non importants) donc les macros Lisp sont essentiellement des plugins pour le compilateur .
  • l'écriture d'une fonction lisp dans lisp qui évalue le code lisp correspond à environ deux pages de code (généralement appelée eval ). dans une telle fonction, vous avez le pouvoir d'introduire toutes les nouvelles règles que vous souhaitez au niveau méta. (le faire fonctionner rapidement demandera cependant quelques efforts ... à peu près de la même façon que d’amorcer une nouvelle langue ...:)

exemples aléatoires de ce que vous pouvez implémenter en tant que bibliothèque utilisateur à l'aide de la métaprogrammation lisp (il s'agit d'exemples concrets de bibliothèques lisp courantes):

  • étendre le langage avec des suites délimitées (hu.dwim.delico)
  • implémentez une macro js-to-lisp-rpc que vous pouvez utiliser en javascript (qui est générée à partir de lisp). il se développe en un mélange de code js / lisp qui poste automatiquement (dans la requête http) toutes les variables locales référencées, les décode du côté serveur, exécute le corps du code lisp sur le serveur et renvoie la valeur de retour au javascript. côté.
  • ajouter un prologue, comme un retour en arrière, au langage qui s'intègre de manière très transparente à " normal " code lisp (voir screamer)
  • une extension de modèle XML au lisp commun (inclut un exemple de < strong> macros de lecteurs qui sont des plugins pour l'analyseur lisp)
  • une tonne de petites DSL, telles que boucle ou itérer pour une mise en boucle facile

La métaprogrammation des modèles est essentiellement un abus du mécanisme des modèles. Ce que je veux dire, c'est que vous obtenez fondamentalement ce que vous attendez d'une fonctionnalité qui était un effet secondaire non planifié - c'est un gâchis et (bien que les outils s'améliorent) une vraie douleur dans le cul parce que la langue ne fonctionne pas vous aider à le faire (je dois noter que mon expérience en matière d’état de la technique est dépassée, car j’ai essentiellement renoncé à cette approche. Je n’ai pas entendu parler de progrès importants, cependant)

J'ai eu du mal à comprendre cela aux environs de 1998, ce qui m'a poussé à rechercher de meilleures solutions. Je pourrais écrire des systèmes utiles qui en dépendent, mais ils étaient infernaux. Les fouilles m'ont finalement conduit à Common Lisp. Bien sûr, le mécanisme du modèle est complet, mais il en va de même pour intercalaire.

Common Lisp effectue la métaprogrammation `right '. Pendant que vous le faites, vous disposez de toute la puissance du langage, sans syntaxe particulière, et comme ce langage est très dynamique, vous pouvez en faire plus.

Il existe bien sûr d’autres options. Aucune autre langue que j'ai utilisée ne fait la métaprogrammation meilleure que Lisp, c'est pourquoi je l'utilise pour le code de recherche. Cependant, vous voudrez peut-être essayer autre chose pour de nombreuses raisons, mais ce ne sont que des compromis. Vous pouvez regarder Haskell / ML / OCaml, etc. Beaucoup de langages fonctionnels ont quelque chose qui approche la puissance des macros Lisp. Vous pouvez trouver des contenus ciblés .NET, mais ils sont tous assez marginaux (en termes de base d'utilisateurs, etc.). Aucun des grands acteurs des langues utilisées industriellement n’a vraiment ce genre de chose.

Nemerle et Boo sont mes favoris personnels pour de telles choses. Nemerle a une syntaxe macro très élégante, malgré une documentation médiocre. La documentation de Boo est excellente mais ses macros sont un peu moins élégantes. Cependant, les deux fonctionnent incroyablement bien.

Les deux. .NET cible, afin qu'ils puissent facilement interagir avec C # et d'autres langages .NET, même les binaires Java, si vous utilisez IKVM.

Éditer: Pour clarifier, je veux dire les macros au sens Lisp du mot, pas les macros du préprocesseur de C. Celles-ci permettent de définir une nouvelle syntaxe et une métaprogrammation lourde à la compilation Par exemple, Nemerle est livré avec des macros qui valideront vos requêtes SQL auprès de votre serveur SQL au moment de la compilation.

Nim est un langage de programmation relativement nouveau qui prend en charge la méta-programmation statique et produit un code compilé efficace (type C ++).

http://nim-lang.org/

Il prend en charge l’évaluation des fonctions au moment de la compilation, les transformations de code AST similaires à celles de lisp par le biais de macros, la réflexion au moment de la compilation, les types génériques pouvant être paramétrés avec des valeurs arbitraires et la réécriture des termes pouvant être utilisés pour créer des fonctions de haut niveau personnalisées optimisations de judas sensibles au type. Il est même possible d'exécuter des programmes externes pendant le processus de compilation qui peuvent influencer la génération de code. Par exemple, envisagez de parler à un serveur de base de données en cours d’exécution locale afin de vérifier que la définition ORM de votre code (fournie via un DSL) correspond au schéma de la base de données.

Le " D " Le langage de programmation est semblable à C ++ mais supporte beaucoup mieux la métaprogrammation. Voici un exemple de traceur de rayons écrit en utilisant uniquement la métaprogrammation au moment de la compilation:

Ctrace

De plus, il existe une branche gcc appelée "Concept GCC". qui supporte les métaprogrammes que C ++ ne fait pas (du moins pas encore).

Concept GCC

Common Lisp prend en charge les programmes qui écrivent des programmes de différentes manières.

1) Données de programme et programme "Arbre de syntaxe abstraite" sont uniformes (expressions S!)

2) defmacro

3) Lecteurs de macros.

4) MOP

Parmi ceux-ci, le véritable esprit-souffleur est MOP. Lisez " Le protocole du métaobjet sur l'art. & Quot; Ça va changer les choses pour vous, je vous le promets!

Je recommande Haskell . Voici un article décrivant ses fonctionnalités de métaprogrammation au moment de la compilation.

Beaucoup de travail dans Haskell: langages spécifiques à un domaine (DSL), spécifications de l'exécutable, transformation du programme, application partielle, calcul par étapes. Quelques liens pour vous aider à démarrer:

La famille de langues ML a été conçue spécifiquement à cette fin. L’une des réussites les plus connues d’OCaml est la bibliothèque FFTW pour les FFT haute performance générées presque intégralement par un code OCaml. programme.

Salut, Jon Harrop.

La plupart des gens essaient de trouver une langue qui a "ultime réflexion". pour l'auto-inspection et quelque chose comme "eval". pour reifier nouveau code. Ces langues sont difficiles à trouver (LISP étant un excellent contre-exemple) et ils ne sont certainement pas grand public.

Mais une autre approche consiste à utiliser un ensemble d’outils permettant d’inspecter, générer et manipuler le code du programme. Jackpot est un tel outil concentré sur Java. http://jackpot.netbeans.org/

Notre boîte à outils de réingénierie logicielle DMS est un tel outil, fonctionnant en C, C ++, C #, Java, COBOL, PHP, Javascript, Ada, Verilog, VHDL et une variété d'autres langues. (Il utilise des frontaux de qualité de production pour lui permettre de lire toutes ces langues). Mieux, il peut le faire avec plusieurs langues au même instant. Voir http://www.semdesigns.com/Products/DMS/DMSToolkit.html

DMS réussit car il fournit une méthode régulière et une infrastructure de support pour un accès complet à la structure du programme en tant que AST, et dans la plupart des cas, des données supplémentaires telles que des tables de symboles, des informations de type, des contrôles et des analyses de flux de données, sont nécessaires à la réalisation de programmes sophistiqués manipulation.

"Métaprogrammation" est vraiment une mauvaise appellation pour cette fonctionnalité spécifique, du moins lorsque vous parlez de plusieurs langues, car cette fonctionnalité n'est nécessaire que pour une tranche étroite de langues qui sont:

  • statique
  • compilé en langage machine
  • fortement optimisé pour les performances lors de la compilation
  • extensible avec des types de données définis par l'utilisateur (OOP dans le cas de C ++)
  • extrêmement populaire

supprimer l'un d'entre eux, et la «métaprogrammation statique» n'a tout simplement aucun sens. par conséquent, je serais surpris si un langage distant à peu près ordinaire avait quelque chose comme ça, comme cela est compris en C ++.

bien sûr, les langages dynamiques et plusieurs langages fonctionnels supportent des concepts totalement différents que l’on pourrait aussi appeler métaprogrammation.

Lisp supporte une forme de "métaprogrammation", bien que cela ne soit pas dans le même sens que la métaprogrammation de modèle C ++. En outre, votre terme " statique " Cela pourrait signifier différentes choses dans ce contexte, mais Lisp prend également en charge le typage statique, si c'est ce que vous voulez dire.

Le méta-langage (ML), bien sûr: http: // cs.anu.edu.au/student/comp8033/ml.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top