La nouvelle édition de mon livre de programmation, Initiation à la programmation avec Scheme, aux Éditions Technip, part à l'imprimerie ces jours-ci. Voici, en avant-goût, le texte de sa conclusion.
Parvenu à la fin de ce livre, le lecteur est en droit de se poser une question : est-il raisonnable de programmer en Scheme, ou plus généralement en Lisp ou quelque autre langage fonctionnel ? Est-il d'ailleurs raisonnable de programmer, tout simplement ?
Il ne fallut pas longtemps après l'invention de l'informatique pour que l'on s'aperçoive du coût élevé de la programmation, et différentes méthodes furent essayées pour le réduire. J'ai tenté de décrire ces méthodes dans le livre Systèmes d'information – Obstacles et succès disponible sur mon site, on peut en dresser la liste :
– inventer de meilleurs langages de programmation ;
– réfléchir à une meilleure organisation du travail du programmeur ;
– inventer des outils pour aider le programmeur à écrire et à manipuler ses programmes ;
– inventer des systèmes de description de programmes, qui peuvent être graphiques, ou textuels, ou les deux, pour améliorer le travail de conception ;
– organiser la production de composants logiciels réutilisables ;
– etc.
Toutes ces méthodes furent appliquées, et toutes apportèrent des améliorations, mais aucune ne permit de réduire la programmation à une activité industrielle. Certaines de ces méthodes, notamment celle des systèmes de description de programmes, postulent la possibilité d'avoir, préalablement à la programmation, une activité de conception, à l'issue de laquelle la programmation serait une tâche mécanique : il n'en est rien, parce que la programmation elle-même est une activité de conception, irréductiblement semble-t-il.
La programmation est au coeur du système technique contemporain, et elle y est pour longtemps : il y a, et il y aura donc, ceux qui savent de quoi il retourne, et ceux qui ne savent pas. C'est pourquoi il est indispensable d'enseigner la programmation à l”école, pour que tout le monde sache, dans un monde où l'informatique occupe une place centrale. Pour s'en convaincre on pourra lire le rapport que Gilles Dowek a rédigé pour l'Académie des Sciences : http://www.lix.polytechnique.fr/~do....
À l'appui de ce point de vue, j'emploierai la comparaison suivante : à l'école tout le monde apprend à calculer des règles de trois, et la règle de trois est une compétence très utile dans la vie de tous les jours. Presque tout le monde, aujourd'hui, apprend également à résoudre des équations du second degré, et nous pouvons sans grand risque écrire que l'immense majorité des élèves des lycées n'auront plus jamais, une fois leurs études terminées, l'occasion de résoudre une équation du second degré. Cet apprentissage est néanmoins très précieux, il confère à ceux qui en ont bénéficié une compréhension très générale d'une démarche utilisée quotidiennement par les ingénieurs, les physiciens et d'autres scientifiques. Savoir, même un peu, ce qu'il en est des équations et des fonctions est une aide considérable pour comprendre l'univers contemporain et la façon dont l'homme y agit. Eh bien il en va de même pour l'apprentissage de la programmation. Voilà pourquoi vous devez savoir programmer. Et tant qu'à apprendre, autant le faire en Scheme, pour les raisons exposées dans l'avant-propos de ce livre.
Quel peut être l'avenir des langages de la famille Lisp, à laquelle appartient Scheme ? Leur position dans le champ de l'informatique théorique est assurée par leur proximité avec le —calcul, mais l'évolution de l'industrie microélectronique leur ouvre de nouveaux horizons. En effet, les progrès techniques des composants électroniques, dont la loi de Moore rend compte, commencent à atteindre des limites fixées par la physique : quand l'épaisseur du diélectrique des transistors se mesure en dizaines d'atomes, on comprend bien qu'il va falloir trouver un autre moyen pour continuer à accroître la puissance de calcul. D'ailleurs les fréquences d'horloge n'augmentent plus guère.
Parmi les autres moyens envisageables pour accroître les performances, utiliser plusieurs processeurs (ou des processeurs multi-cœurs, ce qui revient au même) au lieu d'un seul semble une idée prometteuse. Il est aussi possible d'utiliser plusieurs ordinateurs qui se répartissent le travail, cela s'appelle une grappe (cluster), la liaison entre les unités de calcul est moins intime que dans un multiprocesseur, les problèmes à résoudre sont différents mais pas trop. Répartir un calcul entre plusieurs processeurs pose des problèmes de synchronisation et de coordination qui ne sont pas triviaux : cela s'appelle le calcul parallèle.
Un article publié dans Communications of the ACM (CACM) par Peter J. Denning et Jack B. Dennis [1] a récemment rappelé les questions posées au programmeur par le parallélisme.
Le problème théorique central du calcul parallèle est celui du déterminisme, qui demande qu'un réseau de tâches parallèles en mémoire partagée produise toujours le même résultat à partir des mêmes données, indépendamment des vitesses d'exécution respectives des tâches. Un résultat majeur de la recherche dans ce domaine est le théorème du déterminisme, qui donne une condition suffisante pour garantir le résultat. On peut le résumer en disant qu'il énonce des conditions qui assurent qu'une tâche ne modifiera pas l'état du système pris comme hypothèse par une autre tâche pendant le déroulement de cette dernière.
Il résulte de ce théorème du déterminisme un corollaire selon lequel un programme constitué de tâches concurrentes implanté sans recours à l'opération d'affectation au moyen d'un langage de programmation fonctionnel sera, de façon inhérente (« gratuitement »), déterministe, puisque chaque tâche délivre son résultat à son successeur sans interférence entre leurs zones mémoire respectives.
Les chercheurs en systèmes parallèles avaient un autre sommet à atteindre : la composition de programmes parallèles, c'est-à-dire l'établissement des conditions auxquelles un programme parallèle peut être incorporé, sans modifications, à un programme parallèle plus grand. Il faut pour cela se conformer à trois principes :
– masquage de l'information : l'état interne d'une tâche ne doit pas être accessible à une autre tâche ;
– indépendance du contexte : une tâche ne doit pas dépendre de valeurs extérieures à sa mémoire locale ;
– non-interférence des arguments : si deux tâches concurrentes accèdent à la même donnée, aucune des deux ne doit la modifier.
Les langages de programmation fonctionnels satisfont automatiquement à ces trois principes ; leurs modules sont donc, de façon inhérente, composables.
À ce sujet on consultera avec profit la thèse de Francis Dupont.
Les questions soulevées par la renaissance du parallélisme n'épuisent certes pas celles de l'avenir de la programmation, même si elles en constituent une part notable. Mais la versatilité des langages Lisp, due à leur propriété d'être des langages programmables, garantit, sinon leur avenir industriel, au moins la pérennité des formes de pensée qu'ils vous auront permis d'acquérir : n'est-ce pas le plus important ?
[1] Denning (Peter J.) et Dennis (Jack B.), juin 2010, The Resurgence of Parallelism. Communications of the ACM (CACM), vol. 53, n- 6, pp. 30–32.