- C'est quoi le problème des sommes infinies
- Agit avec prudence — 97 choses à savoir quand on est un programmeur
Lire fait partie de ce qu’on appelle la veille technologique. C’est pour cela que j’essaye, régulièrement, d’avancer dans plusieurs livres réputés du domaine informatique. Aujourd’hui, c’est le premier chapitre du livre The Pragmatic Programmer que je vais résumer à ma façon, en me basant sur la compréhension que j’en ai. En espérant que ça vous plaise, bonne lecture.
Le pragmatisme en programmation, ça s’apprend. Mais pas avec des théorèmes ou des pavés de texte. Le meilleur moyen, c’est d’en décrire les caractéristiques et les façons de penser qui sont propres aux programmeurs pragmatiques. Le chapitre I s’attarde justement sur cet aspect, s’aidant de multiples analogies et exemples.
C’est quoi, le pragmatisme ?
Selon une définition, quelqu’un de pragmatique considère la valeur pratique des choses et expérimente. Cette définition s’oppose à celle de théoricien. Un programmeur faisant preuve de pragmatisme est donc bien aux faits de la réalité du métier et de la pratique au quotidien du développement.
- Il adopte tôt et s’adapte rapidement à de nouvelles technologies, tant par son instinct technologique que par son goût d’essayer et de découvrir.
- Il est curieux et pose de nombreuses questions pour comprendre, être sûr, apprendre. On pourrait même dire qu’il est pointilleux tant il s’intéresse aux détails.
- Il réfléchit mais de façon critique, n’aime pas les réponses du genre « c’est comme ça » et n’est pas naïf pour croire qu’une technologie, un langage ou un système résoudra tous ses problèmes.
- Il est réaliste. Il arrive assez bien à estimer la difficulté d’un projet, ce qui lui permet de ne pas se décourager quand surviennent les difficultés, car il est certain qu’elles arriveront.
- Il reste ouvert en essayant d’être familier avec le plus large panel de technologies et environnements, ce qui lui permet d’intégrer rapidement de nouvelles notions qui le rendent vite efficaces sur de nouveaux domaines.
Enfin, selon les auteurs, un programmeur pragmatique se soucie vraiment de son travail dans une volonté de le faire du mieux possible. L’avis des auteurs est qu’il est inutile d’être développeur si l’on ne se soucie de bien faire son travail. D’ailleurs, pour y arriver, il ne cesse de réfléchir à ce qu’il fait, non seulement pour bien faire maintenant, mais pour toujours continuer à bien faire dans le futur.
Le chat a mangé le code source
Peut-être que les anglo-saxons font du chat ce que les auteurs de bandes dessinées franco-belges font du chien, ce célèbre mangeur de devoirs ou de bulletins trimestriels (Boule et Bill, si vous m’entendez). En tout cas, dans les deux cas, on se rend bien compte que jeter la culpabilité sur un animal est ridicule (et source de gags). Qui irait-voir son supérieur en disans « Désolé chef, j’étais en train de travailler sur le projet hier mais mon chat a tout mangé » ? Mais pourtant, de telles excuses sont sorties, d’une façon moins ridicule certes, mais tout aussi désespérante : « Le code source a disparu suite au crash du disque dur sur lequel il était stocké. »
Aujourd’hui, avec Internet et les gestionnaires de code source, dont Git qui est décentralisé, cette situation est moins probable, mais pas totalement impossible.
La première idée de ce chapitre est qu’un bon programmeur pragmatique ne fournit pas de mauvaises excuses mais des solutions. S’il a accepté une responsabilité, il l’assume ; ainsi, même s’ils portent une partie de la faute, le développeur pragmatique ne va pas jeter la pierre sur un collègue, un chef, un logiciel, une machine, etc. Il va même plus loin en se demandant, avant même d’aller voir les personnes concernées, ce qu’il peut faire pour faire avancer la situation.
- « Le code source a disparu suite au crash du disque dur sur lequel il était stocké. »
- « Le disque dur a planté hier soir, mais une équipe est déjà dessus et nous avons pu récupérer 90% du code source. »
Quelle version préférez-vous ? La réponse est évidente. Pour arriver à la deuxième phrase, un développeur pragmatique doit toujours se poser des questions.
- Ce que je vais dire semble-t-il raisonnable ou bien stupide ? Est-ce que mes propos démontrent mon sérieux et mes efforts ou bien mon manque de prévision et de clairvoyance ?
- Comment la personne en face de moi va-t-elle le prendre ?
- Que vont vraisemblablement dire ces personnes ? Vont-elles proposer des solutions auxquelles je n’ai pas encore pensé ?
Mais l’histoire de notre chat glouton comporte un deuxième enseignement, plus personnel. En effet, un programmeur pragmatique sait que personne, excepté lui, ne prendra en main sa carrière, ses projets et son travail quotidien. S’il veut rester efficace, il sait qu’il a un travail de veille technologique à faire. Il n’aura ainsi pas peur de demander des formations ou des stages plutôt que d’attendre qu’on vienne lui proposer. Dans ses projets et son travail, il sait que c’est à lui de produire des efforts pour obtenir le meilleur possible. Il est tout à fait conscient qu’il a sa part à faire et que personne ne la fera pour lui.
Cela va lui demander de l'humilité et de la modestie. L’humilité va lui permettre d’accepter et de surmonter la peur de l’ignorance et de l’erreur. Aussi pragmatique soit-il, un programmeur est un humain, pétri d’erreurs et à la connaissance limitée et il y aura toujours un problème auquel il n’aura pas la réponse. La modestie, c’est à dire la conscience de ses limites, va l’aider à n’avoir ni honte ni gêne de demander de l’aide. C’est aussi un moyen d’apprendre, d’approfondir, de découvrir ce que nous ne savions pas avant. Seuls les gens orgueilleux et imbus d’eux-mêmes ne veulent pas se remettre en question et se reposent sur leurs acquis.
L’entropie logicielle
L’entropie est, selon le Larousse, ce qui caractérise l’état de désordre d’un système et plus précisément dans notre cas, d’un développement. Plus cette entropie est élevée, plus le développement est tortueux, les évolutions difficiles, les corrections pénibles. Le problème, c’est que le désordre peut commencer avec un minuscule détail qui va vite faire effet boule de neige. C’est le syndrome de la vitre brisée.
Ce syndrome s’observe dans les grandes villes. Quand un bâtiment est inoccupé, s’il est toujours entretenu, si les moindres soucis sont réparés, tout va bien et le bâtiment perdure. Cependant, si une seule vitre vient à être brisée sans être réparée, alors un sentiment d’abandon va transparaître et les dégradations vont s’enchaîner : une deuxième vitre, une troisième, des tags, l’intérieur saccagé, les portes défoncées, etc jusqu’à un tel point où détruire le bâtiment sera préférable à le réparer.
Quel développeur n’a jamais eu à faire face à ce genre de projet qui prend l’eau, ou tout du moins n’en a pas entendu parler ? Mais comment cela se traduit-il concrètement ? Cela peut commencer par des choses très simples : du code mort, redondant, sale, une dette technique qui s’alourdit, etc. Même les meilleurs développeurs, sous le coup de la pression, de la fatigue, de délais serrés, de la flemmardise, peuvent en quelque sorte « briser une vitre » et faire couler un projet si bien parti. Pour s’en prémunir, il convient de remplacer le moindre problème que l’on trouve dans le code et ce, sans tarder. On peut penser aux revues de code et au pair-programming ou tout autre moyen qui n’aurait pas encore été inventé, bref, tout est bon pour corriger le code.
On connait tous des POCs qui passent en production alors qu’ils n’y sont pas destinés. On a tous vu des fixtures dans le code. On a tous remarqué au moins une fois le commentaire //TEMP
présent depuis des années. C’est ce genre de petites entorses sans gravité apparente qui finissent par gangréner une base de code.
Soupe de cailloux et torture de grenouille
Trois soldats affamés sont sur le chemin du retour. Quand ils aperçurent le village qui se dressait à l’horizon, leur esprit reprit vie : ils étaient sûrs qu’ils pourraient manger un petit quelque chose. Mais à leur arrivée, toutes les portes étaient verrouillées et tous les volets fermés. Les villageois, après des années de guerre, tenaient à protéger leur nourriture.
Pas découragés pour autant, les soldats mirent une marmite sur le feu qu’ils remplirent de trois gros cailloux. Les villageois, intrigués, commencèrent à sortir à leur rencontre.
“C’est une soupe de cailloux” expliquèrent les soldats. “Mais c’est tout ? Rien d’autre dedans ?” demandèrent les villageois. “Oui, absolument. Enfin, avec quelques carottes, ça a plus de goût.” Ni une ni deux, un villageois courrait chez lui et revint avec un panier de belles carottes.
“Est-ce vraiment tout ? Eh bien”, répondirent les soldats, “un peu de pomme de terre donnerait du corps à la soupe”. Un autre villageois fit l’aller-retour jusqu’à chez lui.
Les soldats listèrent de cette manière une liste d’ingrédients qui relèveraient le goût de la soupe : de la viande, des poireaux, du sel, des herbes et des épices. Pour chaque ingrédient, un villageois différent amenait sa contribution.
En fin de compte, une soupe bien garnie et nourrissante fut produite par l’ensemble des personnes. Les soldats n’eurent qu’à retirer les cailloux pour que tout le monde puisse profiter d’un repas riche tel que personne n’en avait eu depuis longtemps.
Les soldats sont ici des catalyseurs qui amènent le groupe à produire quelque chose que les individus seuls n’auraient pu faire. Il en résulte que tout le monde gagne. Un programmeur pragmatique va s’efforcer d’être ce catalyseur.
On veut faire quelque chose, une modification et on sait qu’elle est nécessaire. Il y a cependant des risques de perdre du temps dans des réunions et des validations si on demande de but en blanc à modifier le tout. L’astuce va alors consister à bien faire une petite modification, à la montrer aux autres et à dire « C’est sûr, ce serait mieux si … mais bon, ce n’est pas trop important. » Le livre dit que les gens vont rapidement commencer à demander comment implémenter ce fameux truc pas important puis vont le faire.
Je ne sais pas si dans la réalité cela marche à 100%. On a toujours le risque de se dire « Puisqu’il a dit lui-même que ce n’est pas important, aucune raison de le faire. » Par contre, je suis sûr d’une chose, c’est qu’il est plus facile à quelqu’un de s’associer à une opération ayant déjà un certain succès (une petite modification réussie) que de se lancer dans l’inconnu (une grosse modification dont on a aucune certitude sur le succès).
Cette métaphore contient un deuxième enseignement : ne pas trop se laisser absorber par des détails comme les villageois l’ont été par les cailloux. On commence par une nouvelle fonctionnalité, puis par une autre, et encore une autre jusqu’à s’être peu à peu éloigné de la demande de départ, parce que l’on a été trop attentif aux détails et qu’on a perdu de vue l’ensemble.
Connaissez-vous la grenouille qui passe à la bouilloire ? Si on jette une grenouille dans de l’eau chaude, elle en sort immédiatement pour ne pas mourir. Si par contre on la met dans de l’eau froide dont la température va lentement augmenter, la grenouille ne se rend compte de rien et meurt bouillie. L’idée est la même que celle du paragraphe précédent : garder un œil sur le projet en général et pas que sur le travail accompli par nous-mêmes.
Enfin, il convient de bien réfléchir au type de catalyseur que l’on veut être. Allons-nous faire du bien tels des cailloux dans la soupe, ou bien allons-nous avoir des conséquences fâcheuses telle la grenouille tuée par l’eau ? Ceci, cher lecteur, est laissé à ton propre jugement.
Des logiciels de qualité
Aux États-Unis existe une blague mettant en scène une compagnie américaine achetant 100.000 circuits intégrés à un fabriquant japonais. Une des conditions était de n’avoir qu’une pièce défecteuse par lot de 10.000. Quand, quelques semaines plus tard, l’entreprise américaine reçu sa commande, elle remarqua qu’il y avait deux paquets. L’un contenait des milliers de composants ; l’autre, minuscule, n’en contenanait que 10 avec joint un message disant « Voici les pièces défectueuses. »
Une telle qualité est malheureusement bien compliquée à obtenir dans le monde du développement. Les développeurs ont des contraintes de temps, de technologie, de mentalité aussi (certains pourraient se dire « Pourquoi se casser la tête à essayer de faire un excellent produit ? »). Mais ce constat ne nous laisse pas sans espoir. En effet, il est possible de créer des logiciels suffisamment bons.
Cette section du premier chapitre de The Pragmatic Programmer, contrairement à ce qu’on pourrait penser, ne parle pas de la qualité du code (bonne conception, tests unitaires, preuve formelle, etc) mais plutôt de la qualité du produit lui-même. Répond-il aux besoins ? Correspond-il aux attentes du client ? Est-il agréable à utiliser ?
Le livre suggère par exemple d’impliquer tous les utilisateurs et acteurs sur la qualité du produit. On peut faire le lien aujourd’hui avec les méthodes agiles et les délais très courts entre chaque itération qui permet au client d’avoir un retour presque en temps réel sur le produit. L’ajustement par rapport à ses attentes et besoins sera ainsi plus facile et rapide.
Nous, développeurs, sommes habitués aux produits compliquées et aux interfaces obscures. Certains ne jurent même que par ça. Du coup, un produit développé pourrait nous sembler parfait, alors que l’utilisateur final va le trouver trop compliqué. Cela se voit dans le monde du développement mobile, avec des interfaces qui se simplifient et se débarrassent de plus en plus de toute fioriture.
Dans le genre d’écueils à éviter, il y a ceux qui ignorent complètement les utilisateurs ou les contraintes (du projet, de temps, d’argent, etc) simplement pour ajouter une fonctionnalité supplémentaire ou peaufiner le code à l’excès. À l’autre opposé, il est tout peu professionnel de passer outre les bases de la conception et les bonnes pratiques pour tenter de tenir des délais impossibles.
Ces écueils sont-ils imputables uniquement aux développeurs ? Non, il faut aussi que les autres membres du projet (architectes, chefs de projets, commerciaux) jouent le jeu en ne demandant l’impossible ni au client ni aux équipes de développement. Mais là, on tombe dans un autre domaine, celui de la gestion de projet.
La morale de cette section, résumée en une phrase est de faire de la qualité du produit quelque chose d’aussi important que la technique. On conclut avec un piège dans lequel il est facile de tomber par excès de zèle : le perfectionnisme. Le perfectionniste, sous prétexte de vouloir encore plus améliorer, peaufiner, corriger, au final, ne livre jamais rien si l’on ne le force. Pourtant, qui ne préfère pas avoir un bon logiciel aujourd’hui qu’un logiciel parfait demain ?
Un portefeuille de connaissances
Je n’ai pas l’habitude de noter les citations du livre, mais celle-ci m’a paru excellente. En effet, est-ce que la connaissance et l’expérience ne sont pas les aspects les plus précieux et les plus importants pour un développeur ? Et puis, sans investissement, on stagne, nous ne sommes plus à jour, nos connaissances peuvent se périmer (les cours C++ restés en 1996), nous perdons de la valeur au fil du temps qui passe. Investir dans la connaissance est donc important. Commençons donc par voir cinq conseils donné dans le livre.
- Investir régulièrement, pour que ça devienne une habitude. Même si la somme est petite. Tout investissement est bon à prendre.
- Diversifier. C’est la clé du succès à long terme. De plus, la diversification apporte de la valeur : plus on élargie ses connaissances et plus l’on est à même de s’adapter aux situations ou au changement. Pour illustrer, un topic a été créé ici, sur Zeste de Savoir, à propos des langages fonctionnels ; beaucoup d’intervenants conseillaient l’apprentissage d’un de ces langages parce qu’il aide à mieux réfléchir et utiliser les langages impératifs ou objets.
- Sécuriser ses investissements. Un investisseur raisonnable ne va pas placer tout son argent dans des placements à hauts risques, même si ceux-ci peuvent rapporter beaucoup plus. Mais à l’opposé, il ne va non plus tout mettre dans des placements sécurisés mais particulièrement peu rentables. De même, un bon développeur doit apprendre à trouver l’équilibre entre des technologies émergentes qui peuvent disparaitre du jour au lendemain et des technologies matures mais bien ancrées.
- Acheter à bas prix, revendre très cher. Dans la suite directe du point ci-dessus. Apprendre une technologie émergente est parfois une véritable gageure, à cause du manque de documentation, des bugs, du peu de personnes capables de répondre à des questions qu’on se pose, etc. Mais qu’elle devienne populaire et murisse et bing ! le gros lot ! En 2014, apprendre à utiliser Docker pouvait sembler risqué, alors que c’est une valeur sûre en 2019. On peut dire pareil de Vue.js.
- Mettre à jour et rééquilibrer son portefeuille. Un bon exemple est C++. On peut avoir investi dedans avant 2011 et enrichi son portefeuille avec. Mais depuis, il y a du nouveau et il faut réinvestir dedans pour éviter la péremption des connaissances.
Dans la suite du chapitre sont donnés plusieurs conseils pratiques pour se faire.
- Apprendre au moins un nouveau langage par an.
- Lire un livre technique par trimestre.
- Ne pas oublier les livres non-techniques.
- Prendre des cours.
- Participer à des groupes.
- Expérimenter différents environnements (système d’exploitation notamment).
- Rester à jour avec des magazines et revues spécialisées.
- Se connecter à des communautés en ligne.
J’ai tenté et je continue à essayer de suivre plusieurs points.
- Apprendre au moins un nouveau langage par an. Au fil du temps, j’ai eu l’occasion de toucher à de nombreux langages. Je ne suis pas autant à l’aise avec tous. Disons que ceux que je connais le mieux sont C++, Python et C#. On est loin de la règle « Un par an » mais j’expérimente quand même.
- Lire un livre technique par trimestre. Quelques pages par jours aident à terminer assez vite un livre. Je compte finir The Pragmatic Programmer, puis enchaîner sur d’autres « classiques » comme Clean Code ou Working with legacy code. Reste que un tous les trois mois reste un objectif très ambitieux pas forcément accessible à tout le monde.
- Ne pas oublier les livres non-techniques. Cela permet, selon le livre, de se mettre dans la peau d’autres personnes, notamment celles pour qui un ordinateur est une boite noire magique, pour mieux comprendre leur façon de penser. On peut penser à des livres de marketing, de gestion de projet, etc.
- Varier les environnements et les technologies. Si on utilise Windows au travail, on peut utiliser GNU/Linux à la maison.
Mais si apprendre est bien, il ne faut pas donner crédit à tout ce qu’on lit, entend ou voit. N’oublions pas que l’on vit dans un monde rempli d’entreprises et de corporations qui veulent vendre leurs produits, même en informatique. Ce n’est pas parce qu’une page Internet est la première référencée par un moteur de recherche qu’elle est forcément de qualité ou objective.
Ça me rappelle des articles dans le magazine Programmez qui présentent un outil résolvant tel ou tel problème, le dit article étant écrit par la société éditrice de l’outil. De la publicité quoi. Tout n’est pas à jeter, mais il faut néanmoins garder un esprit critique en lisant ce genre de publication.
Communique !
Un développeur communique tout le temps. Dans des réunions avec le client pour comprendre ses besoins. On écrit du code grâce à un langage, signe de notre communication avec la machine. On documente aussi, pour nous-mêmes mais aussi les développeurs futurs. On échange avec son équipe pour définir l’orientation du projet, on défend ses idées, on propose des améliorations. I est donc important d'apprendre à bien communiquer.
- Savoir quoi dire. Nous ne sommes pas des écrivains, nous voulons être clairs mais concis. The Pragmatic Programmer préconise pour cela d’écrire un plan avec les idées que l’on veut développer. Cette technique est valable tant pour les écrits que pour des présentations devant public ou des appels.
-
Connaître son auditoire. Il faut savoir quelles sont leurs connaissances, leurs besoins et leurs intérêts. Parler de langage de programmation ou de framework n’aura pas de sens pour un public de commerciaux. Andy et Dave propose un acronyme regroupant plusieurs questions à se poser : WISDOM .
- What do you want them to learn ? Que veux-tu qu’ils apprennent ?
- What is their interest in what you’ve got to say ? Quel intérêt ont-ils à t’écouter ?
- How sophisticated are they ? À quel point sont-ils spécialistes ?
- How much detail do they want ? Quel niveau de détail veulent-ils ?
- Whom do you want to own the information ? Parmi eux, qui doit s’approprier l’information ?
- How can you motivate them to listen to you ? Comment les motiver à t’écouter ?
- Choisir le bon moment. Mais aussi s’adapter aux priorités de ses interlocuteurs. Le livre donne l’exemple d’un responsable qui vient de se faire incendier par sa supérieure parce que le code source a disparu, expliquant que ce peut être le moment idéal pour lui parler des gestionnaires de code source.
- Adapter son style. Traduction un peu maladroite, mais l’idée est de changer la forme en fonction de la personne. On se doute bien qu’on ne parlera pas de la même façon à ses co-développeurs que devant le plus gros client de la boite. De même, certaines personnes peuvent, pour un moment X, attendre un gros rapport quand d’autres se contenteront d’un mémo ou d’un mail. Le but est de communiquer pour s’adapter.
- Soigner la forme. Là, on parle de productions écrites. À l’heure du material design , de LaTeX, des logiciels de traitements de texte puissants, il n’existe plus d’excuse pour ne pas produire des documents soignés et propres, d’autant plus que beaucoup d’entreprises ont déjà des templates. Mais soigner la forme veut dire aussi soigner la langue, l’orthographe, la grammaire, la conjugaison.
- Impliquer son auditoire. Lui communiquer régulièrement les brouillons du document. Cela peut grandement aider à l’améliorer.
- Écouter. La communication doit être dans les deux sens ; dans le cas contraire, c’est un monologue. Même quand on a toutes les informations, si l’on n’écoute pas les autres, ils ne seront pas enclins à nous écouter. Pour les aider à parler, on peut leur demander de résumer ce qui vient d’être dit, de les questionner pour répondre à d’éventuelles interrogations.
- Répondre. The Pragmatic Programmer propose d’envoyer un simple message signalant à la personne concernée qu’on ne l’oublie pas mais qu’on revient vers elle dès que possible.