# Programmation par intention

En programmation informatique, la programmation par intention (PPI, en anglais intentional programming, IP) est un paradigme de programmation qui permet au code source du logiciel de refléter précisément l'intention du développeur lors de la conception. En respectant le niveau d'abstraction de la pensée du programmeur, la revue et la maintenance des programmes informatiques devient plus facile étant donné que le lecteur du code source n'a plus à comprendre l'implantation que le développeur a choisie pour savoir ce que le programme est censé faire.
Le concept a été introduit par Charles Simonyi alors qu'il dirigeait une équipe chez Microsoft Research. Son groupe a développé un environnement de développement intégré nommé PPI qui démontre ce concept. Pour des raisons encore obscures, Microsoft a interrompu le développement sur PPI au début des années 2000.
Une présentation de la programmation par intention est disponible dans le chapitre 11 du livre Generative Programming: Methods, Tools, and Applications, de Krzysztof Czarnecki et Ulrich Eisenecker.

## Cycle de développement

Comme envisagé par Simonyi, développer une nouvelle application par l'intermédiaire du paradigme de programmation par intention procède comme suit. Un programmeur crée d'abord une boîte à outils spécifique au domaine du problème donné (par exemple l'assurance-vie). Les experts du domaine, aidés par le programmeur, décrivent alors le comportement prévu de l'application selon la manière « ce que vous voyez est ce que vous obtenez » (en anglais : WYSIWYG). En conclusion, un système automatisé utilise la description de programme et la boîte à outils pour générer le programme final. Des changements successifs sont faits seulement au niveau du « tel affichage, tel résultat » (WYSIWYG), utilisant un système appelé l'"atelier de domaine" (en anglais : domain workbench).

## Séparation stockage et présentation du code source

L'avantage principal de la PPI (et un obstacle probable à son acceptation par les communautés de programmeurs) est que le code source n'est pas stocké dans des fichiers textes, mais dans un fichier binaire propriétaire qui ressemble au XML. Comme avec XML, il n'y a aucun besoin d'un analyseur syntaxique spécifique pour chaque morceau de code qui devrait travailler l'information qui forme le programme, abaissant ainsi la barrière à l'analyse d'écriture ou à la restructuration des outils. La vidéo démontre comment le système manipule les langages qui utilisent un préprocesseur basé sur le texte en examinant les utilisations spécifiques des macros dans un corps de code pour inventer une abstraction plus hygiénique.
L'intégration serrée de l'éditeur avec le format binaire apporte certaines des fonctionnalités plus jolies de normalisation de base de données au code source. La redondance est éliminée en donnant à chaque définition à une identité unique et en stockant le nom des variables et des opérateurs dans un emplacement précisément unique. Ceci signifie qu'il est également plus facile de distinguer intrinsèquement entre les déclarations et les références, alors l'environnement montre des déclarations de type en caractères gras. L'espace n'est pas également stocké en tant qu'élément du code source et chaque programmeur travaillant sur un projet peut choisir un affichage d'indentation du source comme ils préfèrent. Des visualisations plus radicales incluent l'affichage des listes de déclarations en tant que boîtes à sous-programmes imbriqués, en éditant les expressions conditionnelles comme des portes logiques ou le re-rendu des noms en Chinois.
Le projet semble normaliser un genre de schéma XML pour des langages populaires comme C++ et Java, tout en laissant aux utilisateurs le mélange de l'environnement et la mise en relation de cela avec les idées d'Eiffel et d'autres langages. Souvent mentionné dans le même contexte que la programmation orientée langage par l'intermédiaire des langages dédiés et la programmation orientée aspect, la PPI prétend fournir quelques percées dans la programmation générative. Ces techniques permettent à des développeurs d'étendre l'environnement de langage pour capturer les constructions spécifiques au domaine sans investir dans l'écriture d'un compilateur complet et d'un éditeur pour n'importe quel nouveau langage.

## Exemple

Un programme en Java qui écrit les nombres de 1 à 10, en utilisant une syntaxe à parenthèses de programmation, peut être comme celui-ci :
Le code ci-dessus contient une commande commune à la plupart des langages de programmation, soit la boucle, dans ce cas représenté par for. Le code, lorsque compilé, lié et exécuté, va boucler 10 fois, augmentant ainsi la valeur de la variable i à chaque itération juste après l'avoir imprimé.
Cependant, ce code ne saisit pas les intentions du programmeur, à savoir « imprimer les numéros de 1 à 10 ». Dans cet exemple simple, un programmeur pourrait fort probablement bien deviner quel est le but du programme sans trop d'effort, mais ce n'est pas toujours aussi simple. Les boucles s'étendant sur de nombreuses lignes, voir des pages, peuvent devenir très complexe à comprendre, notamment si le programmeur n'utilise pas de noms de variables significatifs. Traditionnellement, la seule façon d'indiquer le but du code est d'ajouter des commentaires au code source, mais souvent ils ne sont pas ajoutés, ou ne sont pas clairs, ou il y a un écart de synchronisation avec le code source qu'il est initialement censé expliquer.
Dans les systèmes de programmation intentionnelle la boucle vue ci-haut peut être représentée, à certains niveaux, comme quelque chose d'aussi évident que « imprimer les nombres 1 à 10 ». Le système utiliserait alors les intentions pour générer le code source, produisant probablement quelque chose de très similaire au code vue précédemment. La différence principale dans les systèmes de programmation intentionnelle est qu'ils maintiennent le niveau sémantique, absent du code source lui-même, ce qui peut faciliter considérablement la lisibilité des programmes longs.
Bien que la plupart des langages contiennent des mécanismes pour la capture de certains types d'abstraction, la PPI, comme la famille de langues LISP, permet l'ajout de mécanismes entièrement nouveaux. Ainsi, si un développeur a commencé avec un langage comme le langage C, il serait en mesure d'étendre le langage avec des fonctionnalités comme celles en C++ sans attendre que les développeurs de compilateur l'ajoute. Par analogie, des mécanismes beaucoup plus puissants d'expression pourraient être utilisés par les programmeurs que de simples classes et procédures.

### Identité

La PPI se concentre sur le concept d'identité. Comme la plupart des langages de programmation représentent le code source au format texte, les objets sont définis par nom et leur caractère unique qui doit être déduit par le compilateur. Par exemple, le même nom symbolique pourrait être utilisé pour différents noms de variables, de procédures ou encore de types. Dans le code qui s'étend sur plusieurs pages – ou sur de multiples fichiers pour les noms globalement visibles – il peut devenir très difficile de dire quel symbole se réfère à l'objet actuel. Si un nom est modifié, le code où il est utilisé doit être soigneusement examiné.
En revanche, dans un système de PPI, toutes les définitions attribuent non seulement des noms symboliques mais également des identifiants privés et uniques pour les objets. Cela signifie que, dans le développement de la PPI, chaque fois que vous vous référez à une variable ou une procédure, qui n'est pas juste un nom - il y a un lien vers l'entité originale.
Le principal avantage de cette situation est que si vous renommez une entité, toutes les références qui y sont faites dans votre programme sont changées automatiquement. Cela signifie aussi que si vous utilisez le même nom pour des définitions uniques dans les différents espaces de noms (tel que « .to_string »), vous ne pourrez renommer les mauvaises références comme c'est parfois le cas avec la fonctionnalité de recherche/remplacement dans les éditeurs courants. Cette fonctionnalité le rend également facile d'avoir des versions multi-langages de votre programme. Vous pouvez avoir un ensemble de noms anglais pour tous vos définitions ainsi qu'une série de noms japonais qui peuvent être inversés en à volonté.
Avoir une identité unique pour chaque objet défini dans le programme, c'est également faciliter les tâches de réusinage automatisées, ainsi que la simplification de l'enregistrement du code dans les systèmes de contrôle de version. Par exemple, dans de nombreux systèmes actuels de collaboration de codage (par exemple CVS), lorsque deux programmeurs valident une modification qui est en conflit (par exemple: si un programmeur renomme une fonction et un autre modifie des lignes de cette fonction), le système de versions pensera qu'un programmeur crée une nouvelle fonction pendant qu'un autre modifie une ancienne fonction. Dans un système de version de PPI, il saura qu'un programmeur a simplement changé un nom tandis qu'un autre a changé le code.

### Niveau des détails

Les systèmes de PPI offrent également plusieurs niveaux de détails, ce qui permet au programmeur de «zoomer» ou «dézoomer». Dans l'exemple ci-dessous, le programmeur peut effectuer un zoom arrière pour obtenir un niveau lequel dirait quelque chose comme :
Ainsi les systèmes de PPI sont de l'auto-documentation dans une large mesure, ce qui permet au programmeur de garder un bon niveau élevé de vue de l'ensemble de son programme.

## Travaux similaires

Il y a des projets qui exploitent des idées similaires afin de créer du code avec niveau plus élevé d'abstraction. Parmi ceux-ci on trouve :
* Programmation conceptuelle (en anglais)
* Programmation orientée langage (en anglais)
** Langage dédié
* Programmation orienté sémantique (en anglais)
* Programmation lettrée
* Architecture dirigée par les modèles
* Usine logiciels (en anglais)
* Métaprogrammation
* Lisp (langage de programmation)