Le vrai problème du développement de logiciels

Il y a quelques semaines, j’ai vu un tweet qui disait que l’écriture de code n’est pas le problème. Contrôler la complexité l’est. J’aimerais pouvoir me rappeler qui a dit cela ; Je le citerai beaucoup à l’avenir. Cette déclaration résume bien ce qui rend le développement de logiciels difficile. Il ne s’agit pas seulement de mémoriser les détails syntaxiques d’un langage de programmation ou les nombreuses fonctions de certaines API, mais de comprendre et de gérer la complexité du problème que vous essayez de résoudre.

Nous avons tous vu cela plusieurs fois. De nombreuses applications et outils commencent simplement. Ils font bien 80 % du travail, peut-être 90 %. Mais cela ne suffit pas. La version 1.1 bénéficie de quelques fonctionnalités supplémentaires, davantage intégrées à la version 1.2, et au moment où vous arrivez à la version 3.0, une interface utilisateur élégante s’est transformée en désordre. Cette complexité accrue est l’une des raisons pour lesquelles les applications ont tendance à devenir moins utilisables au fil du temps. Nous constatons également ce phénomène lorsqu’une application en remplace une autre. RCS était utile, mais n’a pas fait tout ce dont nous avions besoin ; SVN était meilleur ; Git fait à peu près tout ce que vous pourriez souhaiter, mais à un coût énorme en termes de complexité. (La complexité de Gits pourrait-elle être mieux gérée ? Ce n’est pas moi qui le dis.) OS X, qui clarifiait autrefois que ça marche, a évolué pour qu’il fonctionne ; le système de type Unix le plus centré sur l’utilisateur jamais construit croule désormais sous le poids de fonctionnalités nouvelles et mal pensées.

Apprenez plus vite. Creusez plus profondément. Voir plus loin.

Le problème de la complexité ne se limite pas aux interfaces utilisateur ; c’est peut-être l’aspect le moins important (bien que le plus visible) du problème. Quiconque travaille dans le domaine de la programmation a vu le code source d’un projet évoluer de quelque chose de court, doux et propre à une masse bouillonnante de bits. (De nos jours, il s’agit souvent d’une masse bouillonnante de bits distribués.) Une partie de cette évolution est motivée par un monde de plus en plus complexe qui nécessite de prêter attention à la programmation sécurisée, au déploiement du cloud et à d’autres problèmes qui n’existaient pas il y a quelques décennies. Mais même ici : une exigence telle que la sécurité a tendance à rendre le code plus complexe, mais la complexité elle-même cache des problèmes de sécurité. Dire oui, l’ajout de sécurité a rendu le code plus complexe est faux sur plusieurs fronts. La sécurité ajoutée après coup échoue presque toujours. Concevoir la sécurité dès le départ conduit presque toujours à un résultat plus simple que de renforcer la sécurité après coup, et la complexité restera gérable si les nouvelles fonctionnalités et la sécurité se développent ensemble. Si l’on prend au sérieux la complexité, la complexité de la création de systèmes sécurisés doit être gérée et contrôlée en phase avec le reste du logiciel, sinon cela ajoutera davantage de vulnérabilités.

Cela m’amène à mon point principal. Nous voyons plus de code écrit (au moins dans la première version) par des outils d’IA générative, tels que GitHub Copilot, ChatGPT (en particulier avec Code Interpreter) et Google Codey. Bien entendu, l’un des avantages des ordinateurs est qu’ils ne se soucient pas de la complexité. Mais cet avantage constitue également un inconvénient majeur. Jusqu’à ce que les systèmes d’IA puissent générer du code de manière aussi fiable que notre génération actuelle de compilateurs, les humains devront comprendre et déboguer le code qu’ils écrivent. Brian Kernighan a écrit : Tout le monde sait que le débogage est deux fois plus difficile que l’écriture d’un programme. Donc, si vous êtes aussi intelligent que possible lorsque vous l’écrivez, comment allez-vous le déboguer ? Nous ne voulons pas d’un avenir composé de code trop intelligent pour être débogué par des humains, du moins pas tant que les IA ne seront pas prêtes à faire ce débogage pour nous. Les programmeurs vraiment brillants écrivent du code qui trouve une issue à la complexité : du code qui peut être un peu plus long, un peu plus clair, un peu moins intelligent pour que quelqu’un puisse le comprendre plus tard. (Copilot exécuté dans VSCode possède un bouton qui simplifie le code, mais ses capacités sont limitées.)

De plus, lorsque nous envisageons la complexité, nous ne parlons pas uniquement de lignes de code individuelles et de fonctions ou méthodes individuelles. La plupart des programmeurs professionnels travaillent sur de grands systèmes pouvant comporter des milliers de fonctions et des millions de lignes de code. Ce code peut prendre la forme de dizaines de microservices fonctionnant comme des processus asynchrones et communiquant sur un réseau. Quelle est la structure globale, l’architecture globale de ces programmes ? Comment restent-ils simples et gérables ? Comment pensez-vous à la complexité lors de l’écriture ou de la maintenance de logiciels susceptibles de survivre à leurs développeurs ? Des millions de lignes de code héritées remontant aux années 1960 et 1970 sont toujours utilisées, la plupart étant écrites dans des langages qui ne sont plus populaires. Comment contrôler la complexité lorsque nous travaillons avec ceux-ci ?

Les humains ne gèrent pas bien ce genre de complexité, mais cela ne signifie pas que nous pouvons la vérifier et l’oublier. Au fil des années, nous avons progressivement amélioré notre capacité à gérer la complexité. L’architecture logicielle est une spécialité distincte qui n’a fait que gagner en importance au fil du temps. Cela devient de plus en plus important à mesure que les systèmes deviennent plus grands et plus complexes, que nous comptons sur eux pour automatiser davantage de tâches et que ces systèmes doivent évoluer vers des dimensions presque inimaginables il y a quelques décennies. Réduire la complexité des systèmes logiciels modernes est un problème que les humains peuvent résoudre, et je n’ai pas encore vu la preuve que l’IA générative le peut. À proprement parler, ce n’est pas une question qui peut encore être posée. Claude 2 a un contexte maximum, la limite supérieure de la quantité de texte qu’il peut considérer en une seule fois, de 100 000 jetons.1; à l’heure actuelle, tous les autres grands modèles de langage sont nettement plus petits. Bien que 100 000 jetons soient énormes, ils sont beaucoup plus petits que le code source, même pour un logiciel d’entreprise de taille moyenne. Et même s’il n’est pas nécessaire de comprendre chaque ligne de code pour réaliser une conception de haut niveau pour un système logiciel, vous devez gérer de nombreuses informations : spécifications, user stories, protocoles, contraintes, héritages et bien plus encore. Un modèle de langage est-il à la hauteur ?

Pourrions-nous même décrire l’objectif de gérer la complexité dans une invite ? Il y a quelques années, de nombreux développeurs pensaient que minimiser les lignes de code était la clé de la simplification et qu’il serait facile de dire à ChatGPT de résoudre un problème avec le moins de lignes de code possible. Mais ce n’est pas vraiment ainsi que le monde fonctionne, ni aujourd’hui, ni en 2007. Réduire les lignes de code au minimum mène parfois à la simplicité, mais conduit tout aussi souvent à des incantations complexes qui regroupent plusieurs idées sur la même ligne, s’appuyant souvent sur des effets secondaires non documentés. . Ce n’est pas ainsi qu’on gère la complexité. Des mantras comme DRY (Dont Repeat Yourself) sont souvent utiles (comme la plupart des conseils de The Pragmatic Programmer), mais j’ai commis l’erreur d’écrire un code trop complexe pour éliminer l’une des deux fonctions très similaires. Moins de répétition, mais le résultat était plus complexe et plus difficile à comprendre. Les lignes de code sont faciles à compter, mais si c’est votre seule mesure, vous perdrez la trace de qualités comme la lisibilité qui peuvent être plus importantes. Tout ingénieur sait que la conception est une question de compromis dans ce cas, entre la répétition et la complexité. Mais aussi difficiles que ces compromis puissent être pour les humains, il n’est pas clair pour moi que l’IA générative puisse les améliorer, voire pas du tout.

Je ne dis pas que l’IA générative n’a pas de rôle dans le développement de logiciels. C’est certainement le cas. Les outils capables d’écrire du code sont certainement utiles : ils nous évitent de rechercher les détails des fonctions de la bibliothèque dans les manuels de référence, ils nous évitent de nous souvenir des détails syntaxiques des abstractions les moins couramment utilisées dans nos langages de programmation préférés. Tant que nous ne laissons pas nos propres muscles mentaux se dégrader, nous serons en avance. Je dis que nous ne pouvons pas être tellement liés à la génération automatique de code que nous oublions le contrôle de la complexité. Les grands modèles de langage ne sont pas utiles pour le moment, même s’ils pourraient le faire à l’avenir. S’ils nous permettent de consacrer plus de temps à comprendre et à résoudre les problèmes de complexité de niveau supérieur, ce sera un gain significatif.

Le jour viendra-t-il où un grand modèle de langage sera capable d’écrire un programme d’entreprise d’un million de lignes ? Probablement. Mais quelqu’un devra écrire l’invite lui indiquant quoi faire. Et cette personne sera confrontée au problème qui caractérise la programmation depuis le début : comprendre la complexité, savoir où elle est inévitable et la contrôler.


Notes de bas de page

  1. Il est courant de dire qu’un jeton correspond approximativement à un mot. Cependant, on ne sait pas comment cela s’applique au code source. Il est également courant de dire que 100 000 mots représentent la taille d’un roman, mais cela n’est vrai que pour les romans plutôt courts.

www.actusduweb.com
Suivez Actusduweb sur Google News


Ce site utilise des cookies pour améliorer votre expérience. Nous supposerons que cela vous convient, mais vous pouvez vous désinscrire si vous le souhaitez. J'accepteLire la suite