J’ai eu l’agréable surprise de trouver dans The Atlantic, magazine grand public, un article sur des thèmes proches de ceux de certaines de mes recherches, qui plus est, ce qui est surprenant pour un magazine américain, avec des mentions de technologies informatiques françaises. J’ai plus de réserves, en revanche, sur le titre (The coming software apocalypse) et ce qui était visiblement un titre de travail (Saving the world from code).

Il me semble que la courte histoire de l’informatique est jalonnée d’articles (dans des revues plus spécialisées) expliquant que les façons de programmer les plus répandues ne pourraient plus durer et qu’il faudrait passer à d’autres approches, naturellement celles promues par la personne qui a rédigé l’article ou les personnes interrogées, suivis d’articles disant le contraire. Je ne retrouve hélas pas les références, mais je me souviens d’articles des années 1970 qui disaient le premier qu’il faut passer aux « méthodes formelles » pour raisonner sur les programmes et ainsi éviter les bugs, le second que ces méthodes formelles ne fonctionnent que sur de petits exemples jouets et ne sont pas adaptés à l’immense majorité des développements logiciels. Ceci devrait nous rassurer sur l’apocalypse à venir : d’autres apocalypses étaient déjà annoncées et ont été surmontées !

Passons maintenant au fond. On peut définir la programmation informatique comme l’activité de passer de la spécification de ce qu’un logiciel devrait faire à un programme effectivement exécutable par un ordinateur, comprenant une phase d’analyse (décomposition du problème en sous-problèmes jusqu’à ce que ceux-ci deviennent traitables par une machine) et une phase de programmation proprement dite, c’est-à-dire le passage d’idées abstraites (algorithmes, structures de données, interactions entre composants…) à un programme. (Ces deux phases ne se succèdent pas forcément dans le temps : on peut commencer de développer le logiciel, avoir un fonctionnement partiel, analyser ce qui manque, le programmer, etc.) La difficulté de la programmation, c’est l’éloignement entre la spécification et ce que la machine sait effectivement faire.

Dans sa forme la plus primitive, la programmation consiste à produire une suite d’instructions en langage machine, c’est-à-dire des codes numériques correspondant à des opérations à faire exécuter (par exemple, il existe un code pour demander une addition). C’est extrêmement fastidieux (il faut non seulement coder les instructions mais aussi se souvenir de numéros désignant les endroits où l’on a stocké les données) tout en nécessitant une grande minutie. Un premier progrès a été la possibilité de programmer en langage d’assemblage, c’est-à-dire en écrivant les noms des instructions (par exemple « add a,5 » pour demander d’ajouter 5 au registre a) et en laissant un logiciel, l’assembleur, calculer tout seul les numéros des stockages de données. Toutefois, cela revenait encore à descendre à un grand niveau de détail technique pour exprimer ce que l’on voulait faire.

On a donc proposé des langages de programmation de plus haut niveau que le langage d’assemblage, en premier lieu Fortran, dont le nom est juste la contraction de l’anglais pour « traducteur de formules ». On écrivait des programmes décrivant des procédures de calcul (pour la physique, l’artillerie, etc.) dans un format textuel assez lisible (par exemple, pour dire que a prend la valeur de trois fois b plus un, on écrivait a=3*b+1, il y avait des ordres pour dire de répéter une séquence d’instructions un certain nombre de fois) et un logiciel appelé compilateur traduisait en langage machine. La productivité des programmeurs était considérablement augmentée : on éliminait l’étape fastidieuse de codage vers le langage d’assemblage voire le langage machine, et les bugs que celle-ci pouvait introduire (bien entendu, à supposer que le compilateur lui-même ne contienne pas de bugs). Il me semble même avoir lu que certains disaient que cela éliminerait les bugs ! Hélas, il restait évidemment les bugs de plus haut niveau : ceux dans l’enchaînement des instructions à répéter, les formules etc. (et éventuellement des fautes d’inattention dans l’écriture du Fortran).

D’une façon générale, l’évolution des langages de programmation, depuis l’époque lointaine du premier Fortran, a tendu vers plus d’expressivité : permettre aux programmeurs d’exprimer ce qu’ils veulent voir exécuté sous une forme plus proche de ce qu’ils ont à l’esprit et avec moins de détails propres au fonctionnement de la machine. Cette évolution a porté tant sur la phase d’analyse que sur celle de programmation. Pour la programmation, il s’agit de pouvoir écrire d’une façon simple des directives qui seront transformées par le compilateur en des suites d’instructions complexes. Pour l’analyse, il s’agit de la fourniture de bibliothèques d’algorithmes et de structures de données déjà prêtes, souvent conçues par des programmeurs plus experts que le programmeur qui les utilisent, et qui lui évitent donc de « réinventer la roue ».

La proposition de l’article d’en venir à une programmation basée sur les modèles est donc une évolution naturelle. Les concepteurs de systèmes automatiques de contrôle (par exemple, de pilotage d’avion) raisonnent en termes de traitement du signal : prendre la mesure d’un capteur, éliminer les variations trop rapides (des parasites), détecter quand il dépasse un certain seuil…, opérations qu’ils représentent à l’aide de boîtes reliées par des fils, par analogie avec les vraies connexions électriques, lorsque chacune de ces boîtes était mise en œuvre par un composant électronique. C’est ce que proposent par exemple Scade, cité dans l’article, ou encore Simulink. Cette représentation est plus visuelle et intelligible pour les ingénieurs automaticiens que la mise en œuvre de ce traitement du signal dans un langage tel que C ou Fortran.

Une représentation de haut niveau, proche du concept que veulent mettre en œuvre les programmeurs, peut permettre par ailleurs la mise en œuvre d’aides au développement, — notamment, dans le cas de l’automatique, des simulations de la chaîne de traitement du signal sur des signaux représentatifs du système physique (par exemple, capteurs et actionneurs d’une aile d’avion), afin de se rendre compte si elle a les propriétés attendues (comme dans Simulink). L’exemple du début de l’article relève de la même idée : plutôt que de demander au programmeur de fixer des coefficients numériques par essai et erreur, on va lui fournir une visualisation instantanée qui lui permettra de les régler.

Toutefois, contrairement à ce que laisse supposer l’article, l’utilisation de tels langages graphiques ne supprime pas les bugs. Prenons le cas de la commande de vol électrique d’un avion de ligne. On va la concevoir graphiquement, à l’aide d’outils adaptés aux représentations des automaticiens spécialistes d’avionique et de contrôle aéronautique, puis (je simplifie) la transformer automatiquement en un logiciel que l’on peut effectivement embarquer dans l’avion. Cette transformation automatique sera à la fois plus fiable et moins coûteuse en personnel qu’une programmation manuelle. Rien ne nous dit toutefois que les lois d’automatique et les dispositifs de protection contre les erreurs et pannes décrits dans la représentation graphique suffisent à garantir la véritable spécification, à savoir « l’avion vole correctement » !

Par ailleurs, pour chaque représentation plus proche des préoccupations du développeur, il faut développer des outils ad hoc. On peut avoir un Scade, un Simulink, pour toutes les applications d’automatique, mais on peut difficilement, pour chaque problème spécialisé, développer un outil destiné à mieux attaquer ce problème.

On entend actuellement en France un discours bien rôdé selon lequel nous ne formerions pas assez de développeurs, les formations des universités et écoles publiques étant inadaptées. Le très médiatique docteur en médecine Laurent Alexandre répond, lui, que de toute façon ces tâches de développement seront bientôt assumées par des intelligences artificielles et qu’il conviendrait donc plutôt de mettre l’accent sur les humanités. Je suis sceptique quant à cette affirmation, qui me semble reposer sur l’anticipation de progrès considérables en intelligence artificielle, dont nous n’avons aucune raison de penser qu’ils se produiront à l’échelle de quelques décennies. Par ailleurs, ce n’est pas la première fois que l’on annonce la fin de la programmation au sens courant du terme. Il me semble bien que l’on avait déjà annoncé dans les années 1980 le remplacement de celle-ci par la programmation logique concurrente et des intelligences artificielles, comme dans le projet japonais d’ordinateur de cinquième génération ; mais ce n’est pas ce qui s’est passé…