14 points par GN⁺ 2025-06-26 | 1 commentaires | Partager sur WhatsApp
  • En 1982, l’équipe logicielle de Lisa chez Apple a instauré une politique de suivi du nombre de lignes de code hebdomadaires de chaque développeur pour préparer la sortie du logiciel
  • Bill Atkinson estimait que le nombre de lignes de code était un mauvais indicateur de la productivité logicielle
  • En réécrivant entièrement le moteur de calcul de régions de Quickdraw, il a supprimé environ 2 000 lignes de code tout en améliorant les performances d’un facteur 6
  • Atkinson a inscrit -2000 sur le formulaire de gestion servant à déclarer le nombre de lignes de code
  • Finalement, les responsables ont cessé de demander à Bill de remettre ce formulaire

L’équipe logicielle de Lisa en 1982 et la politique de suivi des lignes de code

  • Au début de 1982, l’équipe logicielle de Lisa s’est mobilisée avec pour objectif de livrer le logiciel dans les six mois suivants
  • Certains responsables pensaient que suivre le nombre de lignes de code écrites chaque semaine par chaque ingénieur aiderait à faire avancer le projet
  • Pour cela, ils ont mis en place un formulaire hebdomadaire que les ingénieurs devaient remplir chaque vendredi en indiquant le nombre de lignes de code écrites

Le point de vue de Bill Atkinson sur les critères de productivité

  • Bill Atkinson, qui a conçu Quickdraw et l’interface utilisateur, considérait que le nombre de lignes de code ne pouvait pas servir de critère de productivité logicielle
  • Il soulignait que l’objectif était de rendre les programmes aussi petits et rapides que possible
  • Il voyait dans la mesure du nombre de lignes de code le risque d’encourager un code brouillon et inefficace

Refactorisation et optimisation du moteur de régions de Quickdraw

  • Atkinson avait récemment entièrement réécrit le moteur de calcul de régions de Quickdraw avec un algorithme plus simple et plus générique
  • Le résultat de l’optimisation a permis d’accélérer les opérations sur les régions jusqu’à 6 fois
  • Au cours du processus, l’équivalent de 2 000 lignes de code a aussi été naturellement supprimé

La déclaration de -2000 lignes de code et la réaction des responsables

  • En remplissant le premier formulaire de gestion de la semaine, Atkinson a inscrit -2000 dans la case du nombre de lignes de code
  • On ne sait pas clairement comment les responsables ont réagi à ce chiffre
  • Quelques semaines plus tard, on a demandé à Bill de ne plus soumettre le formulaire, ce qu’il a accueilli avec plaisir

1 commentaires

 
GN⁺ 2025-06-26
Commentaires sur Hacker News
  • Le meilleur commit dont je me souvienne reste celui où j’ai supprimé environ 60�00 lignes de code et remplacé tout un « serveur » qui stockait tout l’état en mémoire par une logique légère d’environ 5�00 lignes

    • J’y vois un exploit algorithmique, car ce code était suffisamment léger pour s’intégrer naturellement à d’autres services et n’avait plus besoin d’état en mémoire
    • J’ai découvert qu’il était possible de résoudre un problème d’isomorphisme de sous-graphe guidé sur un arbre donné, ce qui m’a permis de parcourir une seule fois un graphe bidirectionnel orienté générique et de construire le graphe de sortie (un arbre) en ne suivant qu’avec une petite pile les chemins à partir de la racine de départ
    • Le « commit à -60�000 lignes » reste vraiment un moment inoubliable, et je regrette de ne plus avoir rien fait d’aussi impressionnant sur le plan algorithmique depuis
      • Je suis un programmeur amateur qui fait beaucoup de scripting au travail et qui se sent à l’aise dans certains aspects de la programmation, mais chaque fois que j’entends ce genre d’histoire, je me rappelle avec humilité à quel point il existe un immense monde que j’ignore encore, au point qu’une vie entière ne suffirait pas à tout apprendre
      • J’aimerais avoir davantage de contexte. Transformer un programme avec état en programme sans état me paraît presque magique, donc j’aimerais vraiment apprendre comment faire
      • Je suis mathématicien, avec une formation en théorie des graphes et en algorithmique, et je me demande si mes compétences pourraient s’appliquer à ce type de travail concret. Serait-il possible de partager plus de détails ?
      • Le fait que le graphe cible soit un arbre ne me semble pas très important. Le vrai point clé, c’est plutôt la partie « guidée », qui rend possible un parcours en une seule passe
        • On suppose qu’en partant d’un nœud donné dans le graphe d’origine, s’il existe un isomorphisme alors la racine de l’arbre cible doit nécessairement correspondre à ce nœud
        • On peut interpréter le problème comme un parcours du graphe d’origine selon le motif de l’arbre cible, avec false en cas de non-correspondance et true si tout correspond. Même si ce n’est pas un arbre, si le point de départ est clairement fixé, on peut en déduire que cette méthode s’applique à n’importe quel sous-graphe
      • Une blague suggère que les programmeurs de ce genre sont peut-être les ancêtres des questions d’entretien de codage du style « inversez un arbre binaire »
        • Je suis curieux de la théorie des graphes, mais le vocabulaire me paraît difficile. J’aimerais une explication simple pour un développeur ordinaire
  • À l’université, j’ai travaillé pour une entreprise dont la politique managériale affirmait que des débutants pouvaient écrire du bon code ; au final, ils ont fourni un contre-exemple qu’ils n’ont jamais réussi à démontrer faux

    • Après avoir corrigé un bug dans le code et vu exactement le même bug réapparaître, j’ai analysé la situation : au lieu d’ajouter des paramètres à une fonction existante, ils en créaient une copie légèrement modifiée. J’ai ainsi supprimé plus des trois quarts de la base de code, soit plusieurs milliers de lignes de Turbo Pascal
    • Le client du projet était le département Energy, et le programme servait à gérer l’inventaire de matières nucléaires, ce qui m’a valu quelques nuits blanches
      • Mention satirique des avantages du copier-coller de code existant : on ne risque pas de casser la stabilité de l’ancien code, et on améliore même les métriques de « contribution » du manager. Et pour revert, il suffit de supprimer la copie
      • Nous avons aussi un collègue qui duplique souvent le code de cette manière dans notre équipe. Je pense que c’est une habitude prise pour livrer vite sous la pression des demandes urgentes ou des personnes qui parlent le plus fort. Le vrai problème, c’est qu’il faudrait refactorer en fonctions partagées et avoir suffisamment de tests, mais personne ne veut y consacrer le temps nécessaire
      • Des prestataires externes avec qui j’ai travaillé autrefois avaient la même habitude ; quand je signalais que cela pouvait créer de la confusion, ils répondaient : « Dans ce cas, il suffit d’utiliser Ctrl+F »
      • Quelqu’un demande si cet épisode s’est produit dans la région de Blacksburg
      • Mon expérience est similaire : je travaillais dans une entreprise qui exploitait des portails presque identiques dans plusieurs pays d’Asie du Sud-Est. Le code source de chaque portail était stocké dans un dépôt Git séparé, et toute fonctionnalité ou correction de bug commune devait être rétroportée manuellement dans plusieurs copies du code, ce qui était consternant
        • J’ai demandé s’il n’était pas possible de tout mettre dans un dépôt unique avec des feature flags pour personnaliser chaque portail, mais on m’a répondu que non
        • Au final, en deux ou trois mois, j’ai fusionné le code de 4 à 5 portails dans un seul dépôt, ajouté des feature flags et mis à niveau le framework, puis terminé le déploiement sans difficulté. On peut désormais corriger les bugs simultanément sur tous les portails, et le soulagement de ne plus refaire éternellement le même travail manuel est immense
  • Sur un sujet connexe, quelqu’un a rassemblé des fils Hacker News populaires autour du « code à -2000 lignes », comme dans ce lien

    • Il souligne que cette tradition consistant à republier périodiquement d’anciens grands classiques est bénéfique à la fois pour les nouveaux venus et pour les utilisateurs de longue date
      • Je suis une personne simple : si je vois « -2k lines of code », je vote automatiquement
        • Je raconte souvent l’exemple d’Atkinson aux clients qui veulent gérer la mesure de la productivité sur un seul axe métrique. Le véritable indicateur de productivité devrait être l’utilité ; et si quelqu’un arrivait réellement à la quantifier correctement, il serait probablement candidat au prix Nobel d’économie
  • Le projet d’interface web dont je m’occupe comptait 250�00 lignes de code, sans le backend

    • Le développeur précédent était intelligent, mais c’était sa première expérience en JS, et il stockait tout l’état dans des attributs personnalisés du DOM, avec une structure couverte de addEventListener. Je plaisantais en disant : « Si on donne un livre JavaScript à un moine et qu’on l’enferme seul pendant 10 ans, voilà le genre de code qu’on obtient »
    • En quelques mois, j’ai refondu la structure avec des web components et supprimé 50�00 lignes. J’ai ensuite lancé une réécriture complète ; à ce stade, je n’ai retrouvé qu’environ 80 % des fonctionnalités, mais l’ensemble du code ne fait plus qu’environ 17�00 lignes, sans compter des bibliothèques comme Vue/pinia
    • Je vais bientôt supprimer plus de 200�00 lignes, et j’ai l’impression que je ne vivrai probablement jamais quelque chose d’encore plus extrême ; cela donne presque envie de prendre sa retraite
      • J’ai vécu quelque chose de semblable : l’auteur d’origine avait à peine le niveau d’un junior, mais c’était le fondateur de l’entreprise et il était redoutablement productif. Comme il n’avait jamais travaillé en équipe ni collaboré sur le code d’autres personnes, l’architecture contenait absolument tous les code smells imaginables
        • Il y avait des fonctions de plusieurs milliers de lignes, des switch/case/if/else imbriqués, des opérateurs ternaires sur 10 niveaux, des requêtes SQL mélangées à du JS/HTML/HTML injecté avec du JS, et aucun test automatisé, dans une architecture frontend de l’époque PHP/Dojo
      • Quelqu’un fait remarquer que parler d’un « code léger avec seulement 80 % des fonctionnalités » montre justement la limite de ce type de comparaison : si seule une partie des fonctionnalités est implémentée, il est normal de ne pas avoir besoin d’autant de lignes que dans le code d’origine
  • Dans une BD Dilbert, il y a une scène sur les structures de récompense illimitées : le chef de Dilbert promet une récompense financière pour chaque bug corrigé, et Wally lance : « Aujourd’hui, je vais moi aussi coder un minivan ! »

    • Ce genre de situation s’appelle une « perverse incentive » et c’est expliqué dans ce lien de référence
    • Mon manager avait lui aussi affiché cette BD (image) sur le mur de la salle de pause
    • Quelqu’un demande très concrètement ce que signifie « minivan » dans ce contexte
  • Partage d’un cas réel de suppression de 64�00 lignes dans le dépôt dotnet/runtime

    • Le support de l’interop C# + WinRT intégré a été remplacé par un outil de génération de code source, un changement structurel qui nécessitait une décision nette et assumée. Voir ce PR
  • Chaque fois que je vois des statistiques affirmant à quel point les LLM augmentent la productivité des développeurs, cette vieille histoire me revient en tête

    • Objection : l’IA est aussi plutôt douée pour supprimer du code, avec à l’appui un cas amusant partagé dans la communauté de Cursor où « l’IA a tout supprimé »
    • De nos jours, « X % de notre nouveau code est écrit par l’IA ! » est devenu un slogan favori de l’industrie
    • Si l’on inclut même les coûts de construction et de maintenance de nouvelles centrales nucléaires, alors ces chiffres de productivité des développeurs paraissent satiriquement exagérés
  • Je n’ai pas de formation en informatique théorique, et je travaille surtout avec des connaissances acquises sur le terrain

    • Notre projet consiste à restructurer des objets vivants dans une forme lisible par des humains
      • La représentation finale exige de nombreux types très complexes, tandis que la représentation initiale est relativement simple
      • Lorsqu’il y a des nœuds de données similaires, il fallait les comparer puis les fusionner — autrement dit, les extraire sous forme de méthodes et en déduire les paramètres — afin d’améliorer la lisibilité
        • Au début, nous convertissions d’abord vers les types finaux avant de faire les comparaisons, ce qui provoquait une explosion combinatoire des types et rendait la gestion presque impossible, au point que pendant des années les ingénieurs n’arrivaient plus à comprendre la structure
      • Ensuite, j’ai découvert une approche fondée sur une hashmap : distinguer les nœuds partageant la même ossature à l’aide d’une valeur de hachage, les comparer et les fusionner, puis seulement ensuite les convertir vers les types finaux, dans une structure en deux étapes
      • En remplaçant une abstraction centrée sur les types par une abstraction centrée sur les données, même une hiérarchie de classes absurde devient plus facile à gérer via de simples propriétés
      • En résumé, c’était une structure de décompilateur multi-étapes assez stupide, mais nous avons considérablement amélioré la vitesse de traitement et la lisibilité. Il n’existe pas de solution miracle valable partout, mais dans notre cas, le vrai problème était celui des « types », et cette approche nous a beaucoup aidés
  • À l’approche de l’évaluation annuelle, j’ai regardé mes statistiques dans le monorepo interne et découvert qu’en net de code, j’étais devenu quelqu’un qui était en négatif

    • C’était dû à la suppression de code généré automatiquement pour les API et les types, ainsi qu’au retrait d’anciennes versions d’API, mais il y avait quelque chose d’étrangement plaisant dans le fait d’avoir l’impression de venir chaque jour au bureau uniquement pour effacer du code
  • Il y a longtemps, sur un gros projet, j’ai été sidéré par un KPI catastrophique : les chefs de projet tenaient à la main, hors ligne, le nombre de bugs par développeur (bugs corrigés, bugs causés) et l’affichaient au mur

    • J’y ai échappé parce que j’étais sur un projet lié, mais un collègue, inspiré par l’anecdote selon laquelle Lars von Trier aurait découpé uniquement la croix du drapeau danois pour le recoudre en une sorte de drapeau communiste rouge avant de le renvoyer, a découpé la ligne correspondant à son propre compteur de bugs puis l’a recollée en signe de protestation publique. Le lendemain, cette liste avait disparu pour de bon, et cela reste pour moi un souvenir précieux
      • La réponse simple et directe de mon collègue résumait parfaitement toute la situation : « Parce que je ne veux pas figurer sur cette liste ! »
      • Quelqu’un ajoute qu’il a du mal à visualiser concrètement la mise en scène du drapeau et de la liste