La manière même dont on code arrive-t-elle à bout de souffle ? C’est la thèse que défend un long et passionnant article de The Atlantic signé par le journaliste et programmeur James Somers (@jsomers).

Des limites critiques des systèmes logiciels

L’article de James Somers débute par le récit de la panne du 911, le numéro d’urgence, qui a touché l’État de Washington, la région de Seattle, un soir d’avril 2014. Pendant plusieurs heures, impossible de joindre les urgences : tous les appels sonnaient occupés. La raison ? Le système logiciel avait atteint son plafond d’appel, un chiffre maximal que les programmeurs avaient laissé à plusieurs millions, sans penser qu’il serait un jour atteint. D’autres centres de répartition des appels ont été touchés en Californie, Floride, Caroline et Minnesota. Des millions d’Américains signalaient ne pas pouvoir joindre les urgences. Il a fallu attendre le matin pour comprendre et réparer la panne : il suffisait juste de changer un nombre dans un logiciel.

La panne n’a duré qu’une nuit, mais pour Somers, elle montre bien que les systèmes ont changé de nature. Alors qu’avant les appels d’urgence étaient gérés localement, les logiciels ont permis de créer des systèmes à impact global, extrêmement complexes et dont le caractère critique repose sur des millions de lignes de code. Somers rappelle que les défaillances, si elles restent souvent limitées en durée, ont un impact de plus en plus massif et ce d’autant que les logiciels gèrent des infrastructures de plus en plus vastes, complexes et critiques.

« Lorsque nous utilisions des systèmes électromécaniques, nous pouvions les tester de manière exhaustive », regrette Nancy Leveson, spécialiste d’astronautique, d’aéronautique et de sécurité logicielle au MIT. Les systèmes logiciels sont différents parce qu’ils peuvent être changés à moindre coût, qu’ils sont sans cesse mis à jour et bien plus complexes. Pour Leveson, « le problème est que nous essayons de construire des systèmes qui dépassent notre capacité à les gérer intellectuellement ».

Le cadre standard de réflexion sur les défaillances techniques, rappelle Somers, date pourtant des systèmes électromécaniques : on rendait les systèmes fiables en construisant des pièces fiables et en planifiant leurs pannes ou remplacements. Le problème est que le logiciel, lui, ne casse pas comme un rivet défectueux. Quand il échoue, c’est que le logiciel a fait exactement ce qu’on lui a dit de faire : c’est le programmeur qui a été défaillant. « Les échecs logiciels sont des échecs de compréhension et d’imagination ». Mais la complexité de ce qu’on lui demande est invisible à l’oeil nu. Ainsi, aujourd’hui, il n’y a plus de lien mécanique entre la pédale de l’accélérateur et le moteur : vous activez une commande logicielle qui décide de l’air à apporter au moteur. Lorsqu’un programme est en charge de l’accélérateur et des freins, il peut vous ralentir si vous êtes trop près d’une autre voiture ou réguler votre consommation.

Le problème, rappelle Somers, c’est que même ceux qui écrivent des algorithmes ne savent pas toujours vraiment comment ils fonctionnent du fait de leur complexité et de leur intrication. Le logiciel nous a permis de fabriquer les machines les plus complexes qui aient jamais existé, sans que nous l’ayons toujours remarqué, car les voitures d’aujourd’hui ressemblent exactement aux voitures d’hier. Le fait que nous ne voyons pas la complexité ne signifie pas qu’elle a disparu, au contraire : elle est plus présente que jamais.

Si les logiciels sont devenus les pivots du monde que nous construisons, notre confiance dans leur complexité est parfois surestimée. Ce qui rendait la programmation difficile était qu’elle obligeait de penser comme un ordinateur. Mais c’est devenu impossible. Personne ne peut anticiper tout ce qui est contenu dans les 100 millions de lignes de code qui font fonctionner une voiture.

Somers rappelle les incidents qui ont affecté certaines Toyota, avec des accélérateurs et des freins bloqués. Si Toyota a blâmé les conducteurs, la National Highway Traffic Safety Administration qui a mené une longue enquête sur le code des voitures n’a pas trouvé la preuve que le logiciel était la cause, mais a souligné qu’ils ne pouvaient pas prouver que ce n’était pas le cas. Un expert indépendant qui a passé encore plus de temps sur le sujet a montré que l’empilage et le tissage du code des voitures, accumulé et modifié année après année, avaient rendu le code impossible à suivre et empêchait de tester exhaustivement ses défauts. L’équipe de l’expert a démontré qu’il y avait en fait plus de 10 millions de façons pour l’ordinateur de bord d’entraîner une accélération involontaire, que la simple transformation d’un bit dans la mémoire de l’ordinateur pouvait mettre la voiture hors de contrôle et que le code de sécurité mis en place par Toyota n’était pas suffisant pour empêcher ces erreurs. Le logiciel qui regarde le logiciel peut lui aussi être victime d’erreurs. Au final, Toyota a rappelé plus de 9 millions de voitures et payé près de 3 milliards de dollars en amendes liées à quelques cas d’accélérations involontaires.

Pour Somers, ces exemples montrent qu’il est nécessaire d’obtenir de meilleurs résultats, car plus les logiciels deviennent sophistiqués et connectés, en prenant le contrôle de fonctions toujours plus critiques, plus ces problèmes pourraient s’aggraver.

Programmer autrement ?

« Le problème est que même les très bons programmeurs peinent à comprendre les systèmes avec lesquels ils travaillent », explique le développeur Chris Granger (@ibdknox) qui a observé comment les développeurs travaillaient à la mise au point de Visual Studio, un système de Microsoft utilisé par nombre de programmeurs professionnels. Visual Studio, c’est plus de 55 millions de lignes de codes, et 98% d’entre elles ne sont pas pertinentes, estime Granger. Le problème est que c’est un assemblage de plein de travaux différents et pour le comprendre, le parcourir, pour un informaticien, il faut être capable de jouer les fonctions qu’on rencontre dans sa tête. C’est comme jouer aux échecs avec un bandeau sur les yeux : l’essentiel de l’énergie est dépensé à avoir une représentation des pièces et de leurs mouvements… tant et si bien qu’il ne reste plus d’énergie mentale pour penser au jeu lui-même.



Image : Comme IFTTT, Yahoo Pipes, l’outil développé par Yahoo et fermé en 2015, pourrait certainement figurer dans cette liste d’outils qui rendent le code plus accessible, puisqu’il permettait, assez simplement, de combiner des données et des actions, de créer des chaînes d’instructions depuis différents services web, sans avoir à les programmer. Un clone du service, Pipes.digital a récemment relancé le service. Via Korben. .

John Resig (@jeresig), programmeur de logiciels JavaScript et responsable du programme de formation en informatique de la Khan Academy, a remarqué qu’il était difficile d’apprendre à programmer. Quand vous faites un programme, vous entrez des mots. Si vous souhaitez les changer, vous devez changer le texte. Les étudiants qui réussissaient le mieux étaient ceux capables de parcourir le texte dans leur tête, en tentant de suivre les résultats de chaque calcul générés par le texte. Le problème de cette façon de faire est qu’elle devient éminemment complexe avec la multiplication de la quantité de code. Or, si la puissance des ordinateurs n’a cessé de progresser, la programmation, elle – hormis l’évolution des langages – n’a pas changé.

Bref, nos façons de produire des logiciels sont fondamentalement cassées. Comment les réparer ?

Vers une programmation Wysiwyg

Victor Bret (@worrydream) dirige un laboratoire dédié à l’avenir de l’informatique. Mais il semble moins intéressé par la technologie que par la façon dont pensent les programmeurs. En 2012, il a prononcé une conférence qui l’a fait connaître, intitulée « Inventer sur le principe » (vidéo). Il y expliquait que, pour limiter les bugs, les programmeurs avaient besoin d’un lien immédiat avec ce qu’ils créent. A l’époque des premiers traitements de textes, il fallait coder ce que vous vouliez qui apparaisse sans que vous puissiez le voir à l’écran. Il fallait imaginer comment le code allait être interprété par l’ordinateur, donc « jouer l’ordinateur dans votre tête » ou imprimer le texte pour voir ce qu’il rendait. Tout à changé avec les traitements de textes Wysiwyg (« ce que vous voyez est ce que vous obtenez ») : il suffisait alors de mettre un passage en italique pour que les lettres s’inclinent. Juste en regardant votre document, vous étiez d’un coup capable de voir ce qu’il n’allait pas dans la mise en forme de votre texte. Pour Victor Bret, il était temps que la programmation ressemble à cela ! Qu’elle devienne Wysiwig !

Vidéo : la conférence de Victor Bret, « inventer sur le principe ».

Or, certains éditeurs permettent justement d’apporter des fonctions compliquées d’une manière simple, comme c’est le cas de Photoshop, le célèbre éditeur d’image d’Adobe, ou de Squarespace, un système de création et de gestion de sites web très intuitifs. Mais le plus souvent, pour faire des choses intéressantes, il faut écrire du code. Victor Bret a publié quelques démos pour illustrer la manière dont cela pourrait changer. L’une d’entre elles était un jeu, un peu comme Scratch, modifiant le code en modifiant les éléments visuels du jeu ou les caractéristiques du personnage. Une sorte de traitement en temps réel, permettant au développeur lui-même de jouer avec les paramètres, de les adapter, ne consistant non plus à coder, mais à manipuler directement le comportement du jeu. Bien des développeurs présents à cette conférence ont senti devant cette démonstration combien tous leurs outils allaient devenir obsolètes.

Quand Resig a vu les démonstrations de Bret, il a adapté les cours de programmation de la Khan Academy, avec des exercices en regard des programmes. Pour lui, « dans un environnement vraiment réactif, vous pouvez changer complètement la façon dont un étudiant apprend ». Chris Granger de Visual Studio, après avoir vu les conférences de Bret a construit un nouvel environnement de programmation, qui permettait de donner un retour instantané sur le comportement programmé (voir Ce n’est pas le code qui importe, c’est le modèle ! »). C’était le projet Light Table (vidéo), qui a amassé 200 000 $ sur KickStarter en 2012. Ces fonctions Wysiwyg se sont retrouvées dans nombre d’outils de programmation, comme Playground tiré de Swift le langage pour créer des applications Mac et iPhone.

Mais pour Victor Bret, c’était là mal comprendre son propos. Son but n’était pas d’améliorer les outils de programmation. Le code demeurait l’un des pires outils qui soient pour comprendre ce qu’on faisait et lui ajouter un comportement dynamique n’était pas suffisant. Le but de sa conférence « Inventer sur le principe » était de montrer qu’on pouvait atténuer le problème en rendant immédiat le lien entre le comportement d’un système et son code. Mais ce n’était qu’une étape. Dans des conférences ultérieures, il est allé plus loin. Avec « Arrêtez de dessiner des poissons morts » (vidéo) pour les animateurs les invitant à créer des animations intégrant des comportements et « Dessiner des visualisations dynamiques » (vidéo et explication) pour rendre dynamique la visualisation de données scientifiques, il a prolongé le lien entre une interface Wysiwyg et le code. « Je ne suis pas sûr que la programmation doivent continuer à exister », estime Bret. Pour lui, le développeur de logiciel doit créer des outils qui suppriment le besoin de développeurs.

Sortir de l’artisanat de la production logicielle ?

Pour le Français Eric Bantegnie d’Esterel Technologies (Wikipédia) rachetée par Ansys, les seuls produits non industriels qu’on trouve encore dans les produits industriels, c’est le code. Le code est encore trop souvent de l’artisanat par rapport aux autres processus techniques, et quand on parle de logiciels avec 30 millions de lignes de code comme un avion ou 100 millions comme une voiture, ça devient difficile de rester dans l’artisanat. La société d’Eric Bantegnie est l’une des pionnières dans le développement d’applications industrielles logicielles ne nécessitant pas d’écrire de code. Au lieu de cela, les utilisateurs sont amenés à créer des sortes d’organigrammes qui décrivent les règles que les programmes doivent suivre – des modèles – et l’ordinateur génère du code basé sur ces règles. C’est ce qu’on appelle les méthodes formelles. L’idée par exemple est que lorsque vous fabriquez le système de commande d’un ascenseur, la porte s’ouvre ou se ferme quand on appuie sur les boutons adéquats. L’idée est de construire des règles depuis des diagrammes permettant de montrer que la seule façon de faire bouger l’ascenseur est de fermer la porte ou que la seule façon d’ouvrir la porte est de s’arrêter à un étage. Ces méthodes sont surtout utilisées dans le développement de logiciels critiques, car elles permettent de traquer les bugs voire même de les faire totalement disparaître.

Ces logiciels ne ressemblent pas encore tout à fait à Photoshop, où l’image que vous manipulez à l’écran est le produit final. Dans la conception basée sur le modèle, l’image à l’écran ressemble plutôt à un plan. Mais ici, plus besoin de traduire les règles en code. L’énergie est dépensée à architecturer les règles entres elles, pas à coder les règles elles-mêmes. L’enjeu est plus de résoudre le problème que de le coder. Bien sûr, cela nécessite que le travail soit fait en amont, qu’on dispose d’un programme qui transforme des modèles en code et que le code génère ce qu’il est censé faire.

En France, Emmanuel Ledinot, directeur des études scientifiques de Dassault Aviation faisait le même constat dès la fin des années 80 : l’industrie nucléaire et aérospatiale française craignaient qu’à mesure que la complexité augmente, il devienne plus difficile de se prémunir des bugs. L’écriture manuelle d’un code de plus en plus complexe n’était plus viable. Il était nécessaire de changer de méthode.

Avec l’informaticien Gérard Berry (Wikipédia, qui publie L’Hyperpuissance de l’informatique) il a conçu Esterel, un programme pour gérer la complexité des procédures. L’idée de cette approche par le modèle était de créer un modèle du comportement du système centré sur la façon dont chaque événement individuel devait être traité, priorisé, afin de comprendre comment ils dépendent les uns des autres. Une sorte de plan détaillé des programmes utilisés pour effectuer la programmation proprement dite.

Ledinot et Berry ont travaillé pendant 10 ans pour faire qu’Esterel puisse être utilisé en production. Aujourd’hui, leurs produits sont utilisés pour générer du code dans nombre de systèmes critiques comme l’aérospatiale, la défense, l’industrie lourde, les dispositifs médicaux ou les centrales nucléaires. En fait, comme le montre l’exemple de l’aéronautique, nous savons déjà comment rendre des logiciels complexes fiables, via des normes réglementaires rigoureuses, des procédures de conception et de documentation très rigoureuses elles aussi. « Alors pourquoi ne le faisons-nous pas partout ? », interroge James Somers. L’avantage de l’approche basée sur le modèle réside en grande partie dans le fait de pouvoir ajouter des exigences à la volée tout en s’assurant que les exigences existantes sont respectées. A chaque changement, l’ordinateur peut vérifier que le programme fonctionne toujours, sans craindre d’introduire de nouveaux bugs. Comme le dit l’Administration fédérale de l’aviation américaine, le code est « correct par construction », exempt de bugs par sa conception même.

Les programmeurs doivent s’améliorer

Il n’empêche que bien des logiciels restent fabriqués à l’ancienne. Les ingénieurs écrivent leurs exigences en prose et les programmeurs les codent. Il faut dire que les programmeurs aiment écrire du code. Les outils qui écrivent du code et vérifient son exactitude semblent encore ésotériques à beaucoup, pour ne pas dire trop beaux pour être vrais. Tant et si bien, souligne Somers, qu’il faudrait surtout étudier pourquoi les développeurs sont encore si réfractaires à ces nouvelles méthodes.

En 2011, Chris Newcombe est déjà chez Amazon depuis 7 ans. Ingénieur principal, il a travaillé sur certains des systèmes parmi les plus critiques de l’entreprise, comme le catalogue des produits, l’infrastructure de gestion des Kindle ou encore Amazon Web Services, l’infrastructure de traitement et de stockage à la demande… La complexité des systèmes rend les événements censés être extrêmement rare peut-être plus probable qu’on ne le pense. Pour lui, les algorithmes des systèmes critiques sont souvent parfaits, mais les bugs se révèlent plus difficiles à trouver quand les algorithmes deviennent plus complexes. Et la démultiplication des tests ne suffit pas toujours à les repérer. D’où son excitation quand il a entendu parler de TLA+, un mélange de code et de mathématique pour écrire des algorithmes « parfaits ».

TLA+, qui signifie « Logique temporelle des actions », est similaire en esprit à la conception basée sur le modèle : c’est un langage pour écrire les exigences – TLA+ les appelle « spécifications » – des programmes d’ordinateur. C’est lui aussi un système de méthode formelle. Ces spécifications peuvent ensuite être entièrement vérifiées par un ordinateur. C’est-à-dire, avant d’écrire un code, vous écrivez un bref aperçu de la logique de votre programme, avec les contraintes dont vous avez besoin pour y répondre (par exemple, si vous programmez un guichet automatique, une contrainte pourrait être que vous ne pouvez jamais retirer le même argent deux fois d’un compte chèque). TLA+ vérifie alors de manière exhaustive que votre logique réponde bien à ces contraintes. Sinon, il vous montrera exactement comment ils pourraient être détournés.

Ce langage a été inventé par Leslie Lamport, pionnier des systèmes distribués et dont les travaux ont jeté les bases de nombres de systèmes qui sont utilisés par le web. Pour lui, si le logiciel est plein d’erreurs, c’est parce que les programmeurs se précipitent sur l’écriture du code, sur la granularité qui fait fonctionner les programmes. Mais en faisant cela, ils prêtent trop d’attention aux pièces individuelles oubliant trop souvent comment celles-ci s’harmonisent les unes avec les autres. D’où l’idée de TLA+, qui met l’accent sur la structure du système, sa logique, plutôt que sur le code. Newcombe et ses collègues ont utilisé TLA+ pour trouver les bugs de S3 d’Amazon, qui est considéré comme le meilleur service de stockage en ligne. Et TLA+ a été utilisé également pour la Xbox, pour le code de la sonde Rosetta, pour vérifier les puces d’Intel… Reste que TLA+ est peu utilisé, car c’est un langage très mathématique, que les programmeurs maîtrisent peu. Or, souligne Lamport, alors que les enjeux du code n’ont cessé d’augmenter, force est de reconnaître que les développeurs, eux, ne se sont pas améliorés, pas suffisamment en tout cas pour gérer des problèmes de plus en plus complexes…

Pour Newcombe, les programmeurs ne sont pas conscients du fait que les mathématiques puissent les aider à gérer la complexité. Or, pour parvenir à les aider à dépasser leurs limites, il ne suffit pas de leur demander de changer, mais il est nécessaire de changer la manière dont on parle de ces évolutions. Newcombe a créé un cours pour les ingénieurs d’Amazon sur le design du débogage pour arriver à les intéresser à la vérification du code qu’induit TLA+, car ils savent ce que signifie le débogage. Depuis, Newcombe a quitté Amazon pour Oracle, mais continue à faire de la pédagogie. « L’utilisation de ces outils est désormais une question de responsabilité. Nous devons nous améliorer ». Aujourd’hui encore, trop de développeurs regardent sur Stack Overflow, l’une des grandes plateformes de partage pour développeurs, les méthodes des autres, copient des bouts de code et de fonctions, les collent ensembles et les ajustent par itération. Ça fonctionne jusqu’à ce qu’on tombe sur un vrai problème !, souligne Newcombe.

Vers une informatique critique ?

Durant l’été 2015, les spécialistes en sécurité des systèmes Charlie Miller (@0xcharlie) et Chris Valasek ont montré que les constructeurs automobiles ne prenaient les failles logicielles au sérieux en prenant le contrôle d’une Jeep Cherokee, comme l’expliquait Wired. Ils ont profité de la connexion du système de divertissement de la voiture pour prendre le contrôle de la direction, de l’accélération, des freins… Ils ont montré qu’il était possible de créer un virus de véhicule capable d’utiliser l’ordinateur de bord d’une voiture pour en pirater d’autres. Pour Valasek, les constructeurs automobiles assemblent leurs produits depuis des pièces logicielles fournies par des centaines de fournisseurs différents. Si certains codes ont rendu la voiture plus sûre (comme le régulateur de vitesse, le freinage ou l’assistance…), ils ont créé un niveau de complexité inédit qui engendre des problèmes inédits.

Contrairement à l’aéronautique, le monde de l’automobile n’a pas encore pris conscience de l’importance du logiciel. Et le ne le prend pas encore suffisamment au sérieux, estime Gérard Berry. Contrairement au monde de l’aviation, il n’y a pas d’organisme de réglementation de la sécurité logicielle des voitures. La raison est peut-être économique, estime Ledinot. Les constructeurs automobiles ne peuvent pas se permettre d’augmenter le prix d’un composant de quelques centimes puisqu’il est multiplié par plusieurs millions, ce qui explique que les ordinateurs soient réduits au minimum. Le développement logiciel basé sur des modèles est trop coûteux pour eux. Mais la voiture autonome va pousser l’industrie à avoir une approche bien plus critique. Le code des véhicules autonome va avoir la responsabilité de millions de vies demain : il doit fonctionner !

Ce que suggère James Somers dans la conclusion de son article, c’est qu’il est temps de prendre en considération le caractère critique du code et pas seulement pour des systèmes qualifiés de critiques. En janvier 2017, suite aux problèmes électoraux américains, le spécialiste de sécurité informatique, Bruce Schneier (@schneierblog), proposait de faire passer les machines à voter américaines au statut d’infrastructures critiques, un statut qui réglemente déjà nombre d’infrastructures spécifiques. À mesure que le code innerve notre société tout entière, ne faut-il pas commencer à penser à élargir le caractère critique du code à de nouveaux objets ?

Hubert Guillaud