Programmation lettrée
La programmation lettrée (ou programmation littéraire) est une approche de la programmation préconisée par Donald Knuth qui se veut différente du paradigme de programmation structurée des années 1970[1].
« Je crois que le temps est venu pour une amélioration significative de la documentation des programmes, et que le meilleur moyen d'y arriver est de considérer les programmes comme des œuvres littéraires. D'où mon titre, « programmation lettrée ».
Nous devons changer notre attitude traditionnelle envers la construction des programmes : au lieu de considérer que notre tâche principale est de dire à un ordinateur ce qu'il doit faire, appliquons-nous plutôt à expliquer à des êtres humains ce que nous voulons que l'ordinateur fasse.
Celui qui pratique la programmation lettrée peut être vu comme un essayiste, qui s'attache principalement à exposer son sujet dans un style visant à l'excellence. Tel un auteur, il choisit, avec soin, le dictionnaire à la main, les noms de ses variables et en explique la signification pour chacune d'elles. Il cherche donc à obtenir un programme compréhensible parce que ses concepts sont présentés dans le meilleur ordre possible. Pour cela, il utilise un mélange de méthodes formelles et informelles qui se complètent[1]. »
— Donald Knuth, Literate Programming
Le paradigme de la programmation lettrée, tel qu'il a été conçu par Knuth, s'éloigne dans son écriture de l'ordonnancement imposé par l'ordinateur, et à la place autorise les développeurs à utiliser un ordre imposé par la logique et le fil de leur pensée. Les programmes lettrés sont écrits, dans un langage naturel, comme une exposition ininterrompue de la logique, à la manière d'un essai, dans lequel sont incluses des macros qui masquent les abstractions et la complexité.
La programmation lettrée propose des outils pour obtenir, à partir d'un fichier source, deux représentations : l'une utilisée par un compilateur ou un exécutable, le code « emmêlé », et l'autre lue comme une documentation formatée, qui est dite « tissée » à partir de la source lettrée. Alors que les premiers outils de programmation lettrée étaient spécifiques à chaque langage de programmation, la deuxième génération a produit des utilitaires indépendants des langages et existant hors de ceux-ci.
Prémices dans les années 1970
Edsger Dijkstra, dans sa conférence Turing, L'humble programmeur (en)[2], avait mentionné qu'un esprit porté sur la rigueur mathématique et une maîtrise exceptionnelle de la langue maternelle étaient deux caractères essentiels qui faisaient un bon programmeur[3].
En France, Jacques Arsac était réputé dans les années 70 pour ne pas apprécier outre mesure les recours aux ordinogrammes alors à la mode et lui préférer largement le pseudo-code. Claude Pair promouvait, quant à lui, la méthode déductive, très proche de la programmation lettrée[4].
Concept
Un programme lettré est une explication de la logique du programme en langage naturel, comme l'anglais, entremêlée de fragments de code source traditionnel (éventuellement de macros). Les macros, dans un fichier source lettré, se présentent comme des titres ou des phrases en langue naturelle, qui décrivent les abstractions créées au moment de résoudre le problème et cachent le morceau de code ou la macro bas-niveau. Ces macros sont similaires aux algorithmes en pseudo-code souvent utilisés dans l'enseignement des sciences informatiques. Ces phrases explicatives deviennent de nouveaux opérateurs, créés à la volée par le programmeur, formant un méta-langage au-dessus du langage de programmation compréhensible par l'ordinateur.
Un préprocesseur analyse les hiérarchies arbitraires, ou les « toiles interconnectées de macros », pour produire un code source compilable. La commande qui fait cela s'appelle (tangle, emmêler) et la commande associée qui produit la documentation s'appelle (weave, tisser). Le préprocesseur permet aussi d'extraire des macros et d'ajouter du contenu à une macro déjà définie à n'importe quel endroit du texte, permettant ainsi de s'affranchir du besoin de garder à l'esprit les restrictions imposées par les langages de programmation traditionnels et d'éviter d'interrompre le flux de pensée.
Avantages
Selon Knuth, la programmation lettrée permet d'écrire des programmes de grande qualité[1], car elle force le programmeur à exposer clairement sa pensée cachée derrière le code, rendant les mauvaises décisions de conception plus évidentes. Knuth affirme aussi que la programmation lettrée fournit un système de documentation de premier ordre, qui n'est pas un ajout au code, mais en fait naturellement partie dans un processus d'exposition de la pensée, durant la création du programme[1]. La documentation, partie intégrante de la programmation lettrée, permet à l'auteur de reprendre le fil de son cheminement intellectuel là où il l'avait arrêté, même longtemps après, de même qu'elle permet aux autres programmeurs de comprendre la structure profonde du programme.
La programmation lettrée s'affranchit donc de la documentation traditionnelle, dans laquelle un programmeur présente le code source selon une organisation issue des contraintes du compilateur ou doit en déchiffrer l'intention grâce au code et aux commentaires qui y sont associés. Le méta-langage de la programmation lettrée facilite la pensée, en donnant une vue d'ensemble du code et en augmentant le nombre de concepts que l'esprit peut intégrer. Knuth affirme que la programmation lettrée accroît la qualité du code produit[1].
Knuth a appliqué la programmation lettrée à grande échelle à sa présentation de TeX, logiciel très utilisé dans le domaine de l'édition scientifique.
MĂ©conceptions
La programmation lettrée est souvent assimilée à tort[5] à une simple documentation générée à partir d'un seul document source mixant code et commentaires, ou à des commentaires volumineux inclus dans le code. Cette méconception a poussé à considérer les outils d'extraction de commentaires, comme le Plain Old Documentation de Perl, comme des « outils de programmation lettrée ». Cependant, parce que ces outils n'implémentent pas les « toiles de concept abstraits » proposées par les macros en langage naturel, ou ne fournissent pas la possibilité de changer l'ordre du code source, de celui imposé par la machine à celui pratique pour l'esprit humain, ils ne peuvent pas être appelés outils de programmation lettrée telle que définie par Knuth[5].
Exemple
Un exemple classique de programmation lettrée est l'implémentation du programme de compte de mots wc
d'Unix. Knuth a présenté une version CWEB de cet exemple dans le chapitre 12 du livre Literate Programming. Le même exemple a plus tard été réécrit pour l'outil de programmation lettrée noweb[6]. Cet exemple fournit une bonne illustration des éléments principaux de la programmation lettrée.
- Création de macros
Le morceau de code du programme lettré wc
[6] suivant montre comment les phrases arbitraires en langage naturel sont utilisées en programmation lettrée pour créer des macros, qui agissent comme des « opérateurs » dans le langage de programmation lettrée, et masquent les morceaux de code ou les autres macros. La notation de balisage consiste en des doubles chevrons (« <<…>>
») qui indiquent les macros, le signe « @
» indiquant la fin d'une section de code dans un fichier noweb. Le symbole « <<*>>
» indique la « racine », le nœud parent duquel l'outil de programmation lettrée va étendre la toile de macros. En réalité, on peut extraire le code source de n'importe quelle section ou sous-section (c'est-à -dire, un morceau de code désigné par « <<nom du morceau>>=
», avec le signe égal), et un programme lettré peut donc contenir plusieurs fichiers de code source à extraire.
La fonction de wc est de compter les lignes, mots et/ou caractères dans une
liste de fichiers. Le nombre de lignes dans un fichier est […](plus
d'explications)
Ici, voici un résumé du fichier wc.c qui est défini par le programme noweb
wc.nw :
<<*>>=
<<Fichier d'en tĂŞte Ă inclure>>
<<DĂ©finitions>>
<<Variables globales>>
<<Fonctions>>
<<Le programme principal>>
@
Nous devons inclure les définitions d'entrée/sortie standard, puisque l'on veut
envoyer la sortie formatée à stdout et stderr.
<<Fichier d'en tĂŞte Ă inclure>>=
#include <stdio.h>
@
Notez aussi que le démêlage des morceaux de code peut être fait n'importe où dans le fichier texte de programmation lettrée, et pas nécessairement dans l'ordre où ils sont affichés dans le morceau qui les référence, mais dans celui demandé par la logique, reflétée dans le texte explicatif qui enveloppe le programme complet.
- Le programme comme une toile – les macros ne sont pas que des noms
Les macros ne sont pas la même chose que les « noms de section » dans les documentations habituelles. Les macros de programmation lettrée peuvent masquer n'importe quel morceau de code, et être utilisées dans n'importe quelle structure du langage machine bas niveau, souvent à l'intérieur des opérateurs logiques comme « if
», « while
» ou « case
». Ceci est illustré par l'extrait suivant du programme lettré wc
[6].
Le morceau de code présent, qui effectue le compte, a été l'un des plus simples à écrire. Nous regardons chaque caractère et changeons l'état s'il commence ou finit un mot.
<<Parcourir le fichier>>=
while (1) {
<<Remplir le tampon s'il est vide; arrĂŞter Ă la fin du fichier>>
c = *ptr++;
if (c > ' ' && c < 0177) {
/* Codes ASCII visibles */
if (!in_word) {
word_count++;
in_word = 1;
}
continue;
}
if (c == '\n') line_count++;
else if (c != ' ' && c != '\t') continue;
in_word = 0;
/* c est un retour Ă la ligne, une espace ou une tabulation. */
}
@
En fait, les macros peuvent se placer dans n'importe quel morceau de code ou d'autres macros, et sont ainsi plus générales que le « découpage » ascendant ou descendant, ou le découpage en sections. Knuth indique que lorsqu'il a réalisé ceci, il a commencé à penser le programme comme une « toile d'araignée » faite de différentes morceaux[1].
- L'ordre de la logique humaine, pas celle du compilateur
Dans un programme lettré noweb, en plus de l'ordre libre de leurs explications, les morceaux derrière les macros, une fois introduits avec « <<…>>=
», peuvent être continués à n'importe quel endroit du fichier en écrivant simplement « <<nom du morceau>>=
» et en ajoutant plus de contenu à ceux-ci, comme l'extrait suivant le montre (le signe « + » est ajouté par le formateur du document pour la lisibilité et n'est pas dans le code)[6] :
Le compte total doit être initialisé à zéro au début du programme. Si nous avions fait ces variables locales à la main, nous aurions dû faire cette initialisation explicitement. Cependant, les variables globales en C sont automatiquement initialisées à 0. (Ou plutôt « statiquement initialisées », vous saisissez ?)
<<Variables globales>>+=
long tot_word_count, tot_line_count,
tot_char_count;
/* Nombre total de mots, de lignes et de caractères. */
@
- Retenir le cours de la pensée
La documentation d'un programme lettré fait partie de l'écriture du programme. Au lieu de commentaires proposés comme des petites notes sur le code source, un programme lettré contient les explications des concepts à chaque niveau, les niveaux les plus bas étant relégués à une place appropriée, ce qui permet une meilleure communication des idées. Les extraits du wc
lettré ci-dessus montrent comment l'explication du code et sa source sont entremêlés. Une telle exposition des idées crée un flux de pensée qui se rapproche d'un travail littéraire. Knuth a écrit une « nouvelle » qui explique le code du jeu de stratégie Colossal Cave Adventure[7].
Outils
Le premier outil de programmation lettrée publié a été WEB, introduit par Donald Knuth en 1981 pour son système de composition de documents TeX. Il utilise Pascal comme langage de programmation bas niveau et TeX pour la composition de la documentation. Le code source complètement commenté de TeX a été publié dans TeX: The Program, volume B de la série de 5 volumes Computers and Typesetting. Knuth avait déjà utilisé de manière privée un système de programmation lettrée appelé DOC dès 1979. Il a été inspiré par les idées de Pierre-Arnoul de Marneffe[8]. Le programme libre CWEB, écrit par Knuth et Silvio Levy, WEB adapté au langage C et C++, tourne sur la plupart des systèmes d'exploitation et peut produire de la documentation TeX et PDF.
D'autres implémentations du concept de programmation lettrée sont noweb et FunnelWeb, tous deux indépendants du langage de programmation du code source. Noweb est aussi bien connu pour sa simplicité : seulement deux conventions de balisage et deux commandes à invoquer sont nécessaires pour l'utiliser, et permet de formater le texte en HTML plutôt que d'utiliser le système TeX.
FunnelWeb est un autre outil de programmation lettrée qui peut produire de la documentation HTML. Il a un langage de balisage plus compliqué (avec « @ » échappant chaque commande de FunnelWeb), mais a des options plus flexibles.
Nuweb peut traduire un simple fichier de programmation lettrée en n'importe quelle quantité de fichiers sources et utilisant de multiples langages de programmation, et possède une documentation en LaTeX. Il procède en une seule invocation de commande, sans avoir deux commandes séparées pour l'emmêlage et le tissage (« tangle » et « weave »). Il n'est pas aussi extensible que noweb, mais peut utiliser le paquet de listings de LaTeX pour proposer du pretty-printing et le paquet hyperref pour générer des liens dans la sortie PDF. Il a aussi des fonctionnalités de référencement croisé extensibles, incluant des références dans le code généré permettant de retrouver sa position dans la documentation, sous forme de commentaires ainsi que de chaîne de caractères que le code peut utiliser pour reporter son comportement. Vimes est un vérificateur de types pour la notation Z qui montre l'usage de nuweb dans une application pratique. Environ 15 000 lignes de code source nuweb sont extraites en environ 15 000 lignes de C/C++ et plus de 460 pages de documentation. (voir les liens externes.)
Molly est un outil de programmation lettrée écrit en Perl, dont l'objectif est de moderniser et d'étendre la programmation lettrée avec le « pliage HTML » et les « vues virtuelles » du code. Il utilise le langage de balisage de noweb pour les sources lettrées. (voir les liens externes.)
Codnar est un outil de programmation lettrée inversé disponible sous forme de Gem Ruby (voir les liens externes). Au lieu d'extraire le code source de la documentation, le document lettré est extrait du code source. Ceci permet à ces fichiers source d'être édités et maintenus normalement. L'approche est similaire à celle utilisée par des outils populaires de documentation d'API, comme la JavaDoc. Ces outils, cependant, génèrent une documentation de référence, tandis que Codnar génère une description linéaire et narrative du code, similaire à celle créée par les outils de programmation lettrée habituels. Codnar peut coexister avec les outils de documentation d'API, permettant à un manuel de référence et à une explication narrative d'être générés à partir de la même collection de fichiers source.
Leo est un éditeur de texte structuré qui supporte de manière optionnelle les langages de balisage de noweb et CWEB. L'auteur de Leo mélange deux approches différentes : premièrement, Leo est un éditeur de texte structuré, ce qui aide la gestion de larges textes; ensuite, Leo inclut des idées de programmation lettrée, qui dans sa forme la plus pure (c'est-à -dire, la manière dont les outils de Knuth et d'autres, comme noweb, l'utilisent) est possible avec un certain degré d'inventivité et l'utilisation de l'éditeur d'une manière pas exactement prévue par son auteur (dans des nœuds @root modifiés). Cependant, ceci et d'autres extensions (les nœuds @file) rend la structuration du programme et la gestion du texte facile et d'une certaine manière similaire à la programmation lettrée[9].
Le langage de programmation Haskell possède un support natif de programmation semi-lettrée, inspiré par CWEB mais avec une implémentation plus simple. Quand l'objectif est une sortie TeX, on écrit un fichier LaTeX où le code est marqué par un environnement donné ; LaTeX peut être configuré pour gérer cet environnement, pendant que le compilateur Haskell cherche les bons marqueurs pour identifier les expressions Haskell à compiler, retirant la documentation TeX comme si elle était en commentaire. Cependant, comme décrit plus haut, ce n'est pas de la programmation lettrée dans le sens entendu par Knuth. La nature fonctionnelle et modulaire[10] de Haskell rend la programmation lettrée directement dans le langage plus aisée, mais n'est pas aussi puissante que celle des outils WEB où « tangle » peut réorganiser le code dans un ordre arbitraire.
Voir aussi
- TeX – un programme écrit en programmation lettrée
Références
- (en) Cet article est partiellement ou en totalité issu de l’article de Wikipédia en anglais intitulé « Literate programming » (voir la liste des auteurs).
- (en) Donald E. Knuth, « Literate Programming », The Computer Journal, British Computer Society, vol. 27, no 2,‎ , p. 97–111 (DOI 10.1093/comjnl/27.2.97, lire en ligne [PDF], consulté le ).
- Edsger Djiskstra, « The Humble Programmer », Com of the ACM, vol. 15, no 10,‎ (lire en ligne)
- « Besides a mathematical inclination, an exceptionally good mastery of one's native tongue is the most vital asset of a competent programmer. »
- Claude Pair, « La Construction des Programmes », RAIRO Informatique, vol. 13, no 2,‎ , p. 113-137
- (en) Mark-Jason Dominus, « POD is not Literate Programming », Perl.com, .
- (en) Norman Ramsey, « An Example of noweb », (consulté le ).
- Le jeu, aussi connu comme ADVENT, a été à l'origine écrit par Crowther en environ 700 lignes de FORTRAN ; Knuth le refond dans l'idiome WEB. Il est disponible sur (en) literateprogramming.com ou sur (en) le site de Knuth « Copie archivée » (version du 20 août 2008 sur Internet Archive).
- Pierre Arnoul de Marneffe, Holon Programming – Report PMAR 73-23, Université de Liège, Service d'Informatique, .
- (en) Edward K. Ream, « Leo's Home Page », (consulté le ).
- (en) John Hughes, Why Functional Programming Matters, Institutionen för Datavetenskap, Chalmers Tekniska Högskola,, (lire en ligne [PDF]).
Pour aller plus loin
- (en) Donald E. Knuth, Literate Programming, Californie, Stanford University Center for the Study of Language and Information, , 368 p. (ISBN 978-0-937073-80-3)
- (en) Eitan M. Guari, TeX & LaTeX : Drawing and Literate Programming, McGraw Hill, (ISBN 0-07-911616-7) (includes software).
- (en) Kurt Nørmark, « Literate Programming – Issues and Problems », université d'Aalborg,
Liens externes
- literateprogramming.com, site de référence sur le sujet
- comp.programming.literate FAQ sur Internet FAQ Archives
- Literate Programming newsgroup
- LiteratePrograms, wiki qui propose des exemples de codes commentés (à la manière du Python Cookbook)
- « Select »(Archive.org • Wikiwix • Archive.is • Google • Que faire ?), un exemple de programmation lettrée utilisant noweb.
- nuweb, l'outil de programmation lettrée nuweb.
- Vimes, un vrai projet développé avec nuweb.
- z-vimes, autres sources pour Vimes.
- La page Softpanorama sur la programmation lettrée.
- Programmation lettrée en Haskell
- Specification of literate programming in the Haskell Report, le standard Haskell accepté
- Noweb — Un outil de programmation lettrée simple et extensible.
- Molly – Un outil en Perl, qui augmente la programmation lettrée avec du « pliage HTML » et utilise le langage de balisage de noweb.
- Codnar – Un outil de programmation lettrée « inversé »
- Funnelweb – Un outil de programmation lettrée indépendant du langage de programmation.
- Lp4all — Un outil de programmation lettrée simple avec une syntaxe de balisage ressemblant à wiki-wiki.
- pyWeb – Un outil de programmation lettrée qui fonctionne avec n'importe quel langage de balisage et n'importe quel langage de programmation.
- org-babel – Une extension org-mode pour la programmation lettrée dans Emacs.
- Literate Programming in XML – Utiliser Docbook pour la programmation lettrée.
- RawFile – Une extension MediaWiki implémentant une forme basique de programmation lettrée.