Dans un récent article du CACM [1], les auteurs présentent une implémentation des fonctions par étapes . Ils utilisent le terme comme s'il était bien connu, et aucune des références ne ressemble à une introduction évidente.
Ils donnent une brève explication (l'accent est mis sur le mien et le numéro de référence a changé; c'est 22 dans l'original)
Dans le contexte de la génération de programmes, la programmation en plusieurs étapes (MSP, staging en abrégé) telle qu'établie par Taha et Sheard [2] permet aux programmeurs de retarder explicitement l'évaluation d'une expression de programme à un stade ultérieur (donc de mettre en scène une expression). La présente étape agit effectivement comme un générateur de code qui compose (et éventuellement exécute) le programme de la prochaine étape.
Cependant, Taha et Sheard écrivent (c'est moi qui souligne):
Un programme en plusieurs étapes est un programme qui implique la génération, la compilation et l'exécution de code, le tout à l'intérieur du même processus. Les langues à plusieurs étapes expriment des programmes à plusieurs étapes. La mise en scène, et par conséquent la programmation en plusieurs étapes, répondent au besoin de solutions à usage général qui ne paient pas de frais d'interprétation d'exécution.
Ils passent ensuite à plusieurs références à des travaux plus anciens qui montreraient que la mise en scène est efficace, ce qui suggère que le concept est encore plus ancien. Ils ne donnent pas de référence pour le terme lui-même.
Ces affirmations semblent orthogonales, sinon contradictoires; peut-être que ce que Rompf et Odersky écrivent est une application de ce que Taha et Sheard proposent, mais c'est peut-être une autre perspective sur la même chose. Ils semblent convenir qu'un point important est que les programmes (ré) écrivent des parties d'eux-mêmes au moment de l'exécution, mais je ne sais pas si c'est une capacité nécessaire et / ou suffisante.
Alors, qu'est-ce que la mise en scène, respectivement, sont des interprétations de la mise en scène dans ce contexte? D'où vient le terme?
- Staging modulaire léger: une approche pragmatique de la génération de code d'exécution et des DSL compilés par T. Rompf et M. Odersky (2012)
- Programmation MetaML et multi-étapes avec annotations explicites par W. Taha et T. Sheard (2000)
@generated function
s: julia.readthedocs.org/en/latest/manual/metaprogramming/…Réponses:
À ma connaissance, le terme calcul par étapes a été utilisé pour la première fois par Bill Scherlis dans cet article . Auparavant, le terme « évaluation partielle » était utilisé pour à peu près le même concept, mais l'idée de calcul par étapes est subtilement différente. Les deux idées sont liées au théorème Smn de Kleene .
Si vous avez une fonction de deux arguments, mais que vous connaissez un argument, disons m , vous pouvez effectuer immédiatement une partie du calcul de la fonction en utilisant la connaissance du premier argument. Il vous reste alors une fonction ϕ m ( n ) dont les calculs ne dépendent que du deuxième argument, inconnu.ϕ ( m , n ) m ϕm( n )
L'idée de l'évaluation partielle est de calculer automatiquement la fonction spécialisée . Étant donné le code de la fonction d'origine ϕ , l'évaluation partielle effectue une analyse statique pour déterminer quels bits du code dépendent de m et quels bits dépendent de n , et le transforme en une fonction ϕ ′ qui, étant donné m , construit ϕ m . Le deuxième argument n peut alors être appliqué à cette fonction spécialisée.ϕm( n ) ϕ m n ϕ′ m ϕm n
L'idée du calcul par étapes est de penser d'abord à la fonction . On l'appelle une fonction "par étapes" car elle fonctionne en plusieurs étapes. Une fois que nous lui avons donné le premier argument m , il construit le code de la fonction spécialisée ϕ m . Il s'agit de la «première étape». Dans la deuxième étape, le deuxième argument est fourni à ϕ m qui fait le reste du travail.ϕ′ m ϕm ϕm
Le calcul par étapes peut être très important dans la pratique. En fait, chaque compilateur est en fait un calcul par étapes. Étant donné un programme source, il construit un programme cible traduit et optimisé, qui peut ensuite prendre l'entrée réelle et calculer le résultat. Il est difficile d'écrire des programmes de calcul par étapes dans la pratique, car nous devons jongler avec les multiples étapes et nous assurer que les bonnes choses sont faites au bon moment. Tous ceux qui ont écrit un compilateur ont eu des problèmes avec ces problèmes. Il est également difficile d'écrire des programmes qui écrivent d'autres programmes, qu'il s'agisse de programmes en langage machine (compilateurs), de requêtes SQL (manipulations de bases de données) ou de code HTML / Pages de serveur / Javascript (applications Web) et d'une myriade d'autres applications.
la source
Bien que les autres réponses soient techniquement correctes, je ne pense pas qu'elles donnent une bonne compréhension de la raison pour laquelle les informaticiens s'intéressent aux fonctions par étapes.
En créant des fonctions intermédiaires, vous définissez des programmes qui génèrent des programmes. L'un des grands objectifs de la théorie moderne du langage pratique est de maximiser la réutilisation potentielle. Nous voulons permettre d'écrire des bibliothèques qui ne sont pas seulement des fonctions et des objets utiles, mais qui aident les programmeurs en fournissant des constructions architecturales d'ordre supérieur.
Ce serait formidable si nous pouvions nous débarrasser de tout le code passe-partout. Nous devrions être en mesure de minimiser le langage de spécification. Si nous voulons qu'un répartiteur piloté par événement, par exemple, communique avec d'autres répartiteurs avec une conception de thread donnée, nous devrions être en mesure de le spécifier de manière compacte, et tous les écouteurs d'E / S et les connexions d'objet de file d'attente et de thread devraient pouvoir être construits à partir de cette spécification.
Les langues de domaine sont généralement les représentations compactes que nous recherchons. Lorsque les gens travaillent dans un domaine pendant un certain temps, la langue qu'ils utilisent a tendance à supprimer la plupart des doublons d'informations et à devenir une spécification allégée. Cette théorie de la mise en scène tend donc à devenir un système de traduction des langages de domaine vers le langage d'exécution.
Les compilateurs sont techniquement des stagers, mais il manque le but. L'objectif de la mise en scène moderne est de permettre la création de programmes qui créent des programmes afin de maximiser la réutilisation et d'automatiser la construction de programmes dans la mesure du possible. Ce serait formidable si un jour les exigences fonctionnelles d'un programme étaient le programme.
Voir «Programmation générative» de Czarnecki et Eisenecker (ISBN-13: 978-0201309775).
la source
La réponse est donnée dans la partie perspective technique de l'article en question [1]. Le problème considéré est la zone de tension entre le code général et le code spécifique:
Bien sûr, nous voulons résoudre cette tension, c'est-à-dire réaliser un code général et une implémentation spécifique:
Cela a donné lieu à l'idée d'avoir des programmes (généraux) (ré) écrivant eux-mêmes au moment de l'exécution pour s'adapter à une situation spécifique:
Je suppose que le JIT de Java est un bon exemple. Une idée particulière est la programmation en plusieurs étapes, que Lee explique comme ceci:
C'est-à-dire que le "staging" est une manière de regarder les fonctions / codes appropriés qui identifient les phases du calcul / exécution qui peuvent être simplifiées en connaissant les résultats des phases précédentes. Un "retard" du calcul comme dans la première citation de la question peut être un effet secondaire nécessaire pour séparer correctement les étapes, mais ce n'est pas le point.
Rompf et Odersky citent la transformation de Fourier rapide comme exemple qui peut être instructif.
la source