Une traduction d’un article de Bruce
Schneier intitulé Rare Risk and Overreactions qui traite de nos
réactions faces aux événements impressionnants.
Tout le monde a réagi au terrible événement que constitue la fusillade de Virginia Tech. Certaines de ces
réactions étaient rationnelles, d’autres pas.
Un étudiant a été suspendu pour avoir personnalisé un jeu de tir à la première
personne avec une carte de son école. Un fonctionnaire a été licencié pour avoir parlé d’une arme, puis a reçu une visite de la police quand
il a créé une bande dessinée inspirée de l’incident. Un conseiller de Yale a
interdit l’utilisation de fausses armes réalistes dans les théâtres de l’université – décision qui a
été annulée dans
la journée. Et des enseignants ont terrorisé une classe de sixième en mettant en scène
une attaque à main armée, sans leur dire qu’il s’agissait d’un exercice.
Toutes ces choses ont eu lieu, même si des fusillades aussi graves sont incroyablement rares, même si – selon
la presse – moins d’un pour cent (.pdf) des homicides et des suicides des enfants âgés
de 5 à 19 ans ont lieu dans des écoles. En fait, ces réactions ont eu lieu, non pas en dépit de ces faits,
mais à cause d’eux.
Le massacre de Virgina Tech appartient précisément au type d’événement auquel nous les humains avons tendance
à surréagir. Nos cerveaux ne sont pas très bons ni en probabilité ni en analyse de risque, encore moins
lorsqu’il s’agit d’événements qui surviennent rarement. Nous avons tendance à exagérer les faits
spectaculaires, étranges, et rares, et à minimiser ceux qui sont ordinaires, familiers et courants. Dans la
communauté des psychologues, il y a de nombreuses recherches sur la manière dont le cerveau répond aux
risques – j’ai déjà
parlé de certaines d’entre elles – mais l’élément fondamental est le suivant : notre cerveau
est bien meilleur quand il s’agit de traiter des risques simples que nous avons dû prendre en compte durant
la plus grande partie de l’existence de notre espèce, et bien plus mauvais pour évaluer les risques
complexes que la société nous impose aujourd’hui.
Nouveauté plus terreur égale réaction disproportionnée
On peut en observer les effets en permanence. Nous avons peur d’être tués, kidnappés, violés et agressés par
des étrangers alors qu’il est bien plus probable que l’auteur d’un crime de ce genre soit un
parent ou un ami. Nous craignons les accidents d’avion et les tireurs fous au lieu des accidents automobiles
et des violences domestiques — tous les deux bien plus courants.
Aux États Unis, les chiens, serpents, abeilles et cochons font
chacun plus de victimes chaque année (.pdf) que les requins. En fait, les chiens tuent plus de personnes
que n’importe quel animal à part les humains. Il est vrai que les requins sont plus dangereux que les
chiens, mais il est bien plus probable de rencontrer un chien qu’un requin.
Notre réaction récente la plus disproportionnée à un événement rare a été notre réponse à l’attaque
terroriste du 11 septembre. Je me souviens de John Ashcroft, alors ministre de la Justice, faisant un
discours en 2003 dans le Minnesota — où je vis — et prétendant que l’absence d’attaque terroriste
depuis le 11 septembre prouvait l’efficacité de sa politique. J’ai pensé : "Il n’y a pas eu d’attaque
terroriste pendant les deux années qui ont précédé le 11 septembre, et tu n’avais aucune politique.
Qu’est-ce-que ça prouve ?"
Cela prouve que les attaques terroristes sont très rares, et peut-être que notre réaction ne valait pas
l’énorme dépense : la perte de liberté, les attaques de notre Constitution et la perte de crédibilité
au niveau mondial. Néanmoins, surréagir était pour nous ce qu’il fallait faire. C’est effectivement de la
sécurité de pacotille, mais cela nous rassure.
Les gens ont tendance à baser l’analyse de risque sur leurs histoires personnelles plutôt que sur des données
objectives, malgré le vieil adage qui dit que "le pluriel d’une anecdote n’est pas une généralité". Si
un ami se fait agresser dans un pays étranger, cette histoire a plus de chance d’avoir une influence sur
votre sentiment du risque à voyager dans ce pays que des statistiques de crime abstraites.
Les interlocuteurs que nous connaissons sont plus crédibles que les étrangers, et les histoires qui sont
proches de nous ont plus de poids que celles de pays étrangers. En d’autres termes, la proximité de la
relation influence notre évaluation du risque. Et qui est de nos jours l’interlocuteur principal de tout le
monde ? La télévision
(l’excellent livre de Nassime Nicolas Taleb, Le cygne noir : l’impact de l’improbable, traite de cela.)
Considérons la réaction à un événement survenu le mois dernier : le joueur de base-ball professionnel
Josh Hancock qui avait bu, se tue dans un accident automobile. En conséquence de quoi, plusieurs équipes de
base-ball ont interdit l’alcool dans leurs loges après les matchs. Sans parler du fait qu’il s’agisse d’une
réaction ridicule à un événement incroyablement rare (2430 matchs de base-ball par saison, 35 personnes par
loge, deux loges par match, et combien de fois est-ce arrivé ?), cette solution n’a aucun sens. Hancock
n’a pas bu dans la loge : il a bu dans un bar. Mais la ligue de base-ball avait besoin de montrer
qu’elle avait fait quelque chose, même si ce quelque chose n’a aucun sens — encore moins si ce quelque chose
augmente en réalité le risque en forçant les joueurs à boire dans des bars au lieu des loges, où la pratique
est plus contrôlée.
Je dis aux gens que, si c’est dans l’actualité, ne vous inquiétez pas. La définition précise d’"actualité"
est "quelque chose qui arrive rarement". C’est quand quelque chose n’est pas dans l’actualité, quand c’est
si habituel qu’on n’en parle plus — accidents automobiles, violence domestique — que vous devriez commencer
à vous en préoccuper.
Mais ce n’est pas la manière dont nous pensons. Le psychologue Scott Plous l’a dit justement dans La
psychologie du jugement et de la prise de décision : "En termes généraux : (1) Plus un événement
est visible et plus il semblera fréquent ou probable ; (2) plus une information est impressionnante,
plus elle est convaincante et plus facilement on s’en souviendra ; (3) plus quelque chose est marquant,
plus cette chose semblera causale".
Par conséquent, face à un événement très visible et extrêmement impressionnant comme le 11 septembre ou la
fusillade de Virginia Tech, nous réagissons de manière disproportionnée. Et en face de tous les événements
marquants et liés, on suppose une causalité. En votant le Patriot Act, nous pensons qu’en distribuant des
armes aux étudiants, ou peut-être en rendant plus difficile à un étudiant d’avoir des armes, nous aurons
résolu le problème. Nous ne laissons pas nos enfants aller jouer sans surveillance. Nous évitons de nous
baigner parce que nous avons lu quelque chose sur les attaques de requin.
C’est encore notre cerveau. Nous avons besoin de “faire quelque chose”, même si ce quelque chose
n’a pas de sens ; même si c’est inefficace. Et nous avons besoin de faire quelque chose qui soit
directement lié aux détails de l’événement en question. Alors plutôt que de mettre en place des mesures
efficaces, mais plus générales, pour réduire le risque terroriste, nous interdisons les cutters à bord des
avions. Et nous repensons après-coup au massacre de Virginia Tech et nous récriminons contre nous-même à propos de ce qui aurait
dû être fait.
Finalement, notre cerveau a besoin de quelqu’un ou de quelque chose à condamner (Jon Stewart a un excellent papier sur la recherche de bouc émissaire de Virginia Tech, et la
couverture des médias en général). Mais parfois il n’y a pas de bouc émissaire à trouver ; parfois tout
a été fait correctement et il s’agit seulement de malchance. Simplement nous ne pouvons pas empêcher un
forcené isolé de tirer au hasard sur des gens ; il n’existe aucune mesure de sécurité qui serait
efficace.
Aussi circulaire que cela puisse paraître, les événements rares sont rares principalement parce qu’ils ne
produisent pas très souvent, et non en dépit de mesures de sécurité préventives. Mettre en œuvre des mesures
de sécurité pour faire en sorte que ces événements rares le soient encore plus ressemble à la blague de
l’homme qui patrouille bruyamment autour de sa maison pour maintenir les éléphants éloignés.
"Des éléphants ? Il n’y a pas d’éléphants dans le coin," dit un voisin.
"Vous voyez bien que ça fonctionne !"
Si vous voulez prendre des mesures de sécurité qui aient du sens, déterminez les points communs dans un
groupe d’événements rares et concentrez-y vos contre-mesures. Concentrez-vous sur le risque général de
terrorisme, pas sur les menaces spécifiques d’attentat aérien utilisant des explosifs liquides.
Concentrez-vous sur les risque généraux des jeunes adultes perturbés, et pas la menace spécifique d’un
forcené isolé errant sur un campus universitaire. Ignorez les menaces qui
ressemblent à des scénarios de films, et concentrez-vous sur les vrais risques.
Ce texte est paru initialement sur Wired.com, mon 42ème texte sur ce site.
© 2007 Bruce Schneier
Une traduction d’un article de Steve Yegge
Je suis un programmeur, et aujourd’hui je suis en congé. Devinez ce que je suis en train de faire ? J’aurais
adoré vous dire que je suis en train de siroter des Mai Tais aux Bahamas, mais ce que je fais vraiment pendant mon
congé, c’est programmer.
Donc ce congé ne l’est que du point de vue des RH – officiellement je ne travaille pas, pour me donner du temps
libre afin de remettre mon jeu vidéo en ligne. J’ai commencé à écrire sur ce jeu il y a dix ans, et j’ai
passé sept ans à le développer. Il n’est plus en ligne depuis un moment et je dois l’y remettre, en
partie pour que les joueurs arrêtent de me traquer. Ça va me prendre au moins une semaine en y passant mes journées,
j’ai donc dû prendre un congé pour y arriver.
Pourquoi mon jeu est-il hors-ligne ? Pas par manque de popularité. C’est un jeu qui a pas mal de succès
pour un effort fourni principalement à temps partiel par une seule personne. Un quart de million de personnes l’ont
essayé (elles sont allées aussi au moins jusqu’à créer un personnage), et pendant ces années des dizaines de
milliers de personnes ont passé d’innombrables heures à y jouer. Il a gagné des prix et on a parlé de lui dans
des magazines. Il a attiré l’attention de portails de jeux, d’investisseurs potentiels et d’écoles
entières pleines d’enfants.
Hé oui, des enfants. C’était supposé être un jeu pour des étudiants, mais il a été étonnamment populaire auprès
des adolescents et même des pré-adolescents, qu’on penserait plutôt jouer à un jeu de console en 3D ou d’autres
choses. Mais je l’ai écrit pour moi, et il y a apparemment assez de gens qui aiment le même genre de jeux que
moi pour que se créée une communauté viable.
J’ai mis le jeu hors ligne pour toutes sortes de raisons banales — il avait besoin de mises à jour, j’étais
occupé, je n’avais pas beaucoup de temps en soirée, etc. Mais ces raisons banales revenaient vraiment à un
seul problème plus profond : la base de code [1] est trop grande pour qu’une
personne seule s’en occupe.
J’ai passé presque dix ans de ma vie à construire quelque chose qui est trop gros.
J’ai beaucoup réfléchi à ça – plus que vous ne le penseriez probablement. Cela a occupé une grande part de mes
réflexions techniques ces quatre ou cinq années dernières, et cela m’a aidé à mettre en forme tout ce que j’ai
écrit pendant ce temps, à la fois dans mes blogs et dans mon code.
Pour le reste de cette petit déclaration, je vais supposer que vous êtes un étudiant jeune et intelligent, en âge d’aller
à l’université ou même au lycée et qui voudrait devenir un meilleur programmeur, peut-être même un excellent
programmeur.
(S’il-vous-plaît, ne pensez pas que je sous-entends que je suis un excellent programmeur. Loin s’en faut.
Je suis un programmeur qui a commis des décennies d’atrocités dans son code, et dans ce processus j’ai
appris quelques leçons que je vous transmets dans l’espoir qu’elles vous aideront dans votre quête pour
devenir un excellent programmeur.)
J’ai besoin de supposer que vous êtes jeune pour faire ma démonstration, parce que si je suppose que je suis en
train de parler à des programmeurs "expérimentés", ma pression sanguine va augmenter et je ne serai pas capable de
me concentrer suffisamment longtemps pour terminer ma déclaration. Vous verrez pourquoi sous peu.
Heureusement pour moi, vous êtes jeune et impatient d’apprendre, donc je peux vous dire comment les choses sont
vraiment. Contentez vous de garder les yeux ouverts pendant les prochaines années, et vous verrez si j’ai
raison.
Point de vue minoritaire
Il se trouve que j’ai une opinion durement acquise et minoritaire à propos des bases de code. En particulier je
crois, et même plutôt résolument, que la pire chose qui puisse arriver à une base de code c’est de
déborder.
Je dis "déborder" à défaut pour désigner une idée raisonnablement bien-formée pour laquelle je n’ai semble-t-il
pas de meilleur mot dans mon vocabulaire. Je vais devoir en parler jusqu’à ce que vous voyiez ce que je veux
dire, et peut-être me fournirez-vous un meilleur mot. Le mot "bouffi" pourrait être plus précis, puisque tout le
monde sait que "bouffi" est mauvais, mais malheureusement la plupart des soi-disant programmeurs expérimentés ne
savent pas comment détecter des boursouflures, et ils parleront de bases de code sévèrement bouffies en affirmant qu’elles
sont minces comme un fil.
C’est une bonne chose qu’on ne leur parle pas, non ?
Je dis que mon opinion est durement acquise parce que les gens ne parlent pas beaucoup de la taille des bases de code ;
ce n’est pas un problème largement reconnu. En fait c’est largement reconnu comme un non-problème. Cela
signifie que quiconque partage mon opinion est considéré comme à moitié fou, vu qu’aucune personne sensée ne
se préoccuperait d’un non-problème.
Dans l’industrie [2], les gens sont très excités par diverses idées qui sont sensées vous
aider à travailler avec de grandes bases de codes, comme des IDEs [3] qui peuvent manipuler le
code comme des "structures algébriques", et des index de recherche et ainsi de suite. Ces personnes ont tendance à
voir les bases de codes comme les personnes du BTP voient la boue : ils veulent de grosses machines qui peuvent
déplacer la boue comme-ci et comme-ça. La loi de la conservation de la boue s’applique : la boue ne peut
pas être compressée, pas beaucoup, alors les solutions possibles consistent en différents manières de la déplacer.
Il y a même des questions pour des entretiens d’embauche de programmeurs, probablement métaphoriques, sur la
manière dont on pourrait s’y prendre pour déplacer une montagne entière de boue, un camion à la fois.
Les programmeurs de l’industrie se passionnent pour des solutions à un grand non-problème. C’est juste
une montagne de boue, et on a seulement besoin de grand outils pour la déplacer. Les outils sont passionnants mais
la boue ne l’est pas.
Mon opinion minoritaire est qu’une montagne de code est la pire chose qui puisse arriver à une personne, une
équipe ou une entreprise. Je pense que le poids du code brise des projets et des entreprises, qu’au-delà d’une
certaine taille il force à réécrire le code, et que les équipes futées feront tout ce qui est en leur pouvoir
pour empêcher leur base de code de devenir une montagne. Outils ou pas outils. C’est ce que je crois.
Il se trouve que quelque chose de mal doit vous arriver avant que vous puissiez partager mon opinion minoritaire. La
mauvaise chose qui m’est arrivée c’est que j’ai écrit un beau jeu dans un affreux langage, et que
le résultat était ravissant à l’extérieur et plutôt terrifiant à l’intérieur. Le programmeur moyen de l’industrie
d’aujourd’hui ne trouverait pas grand-chose à redire à ma base de code, à part l’absence de tests
unitaires [4] (ce que je regrette maintenant) qui hélas doubleraient la taille de ma base de
code de 500.000 lignes qui est déjà énorme. Donc la principale chose qu’ils trouvent à redire est que, d’un
certain point de vue, il n’est pas assez gros. Si j’avais fait les choses comme il se doit, selon les
modes du moment, les choses seraient encore pires qu’elles ne le sont déjà.
Certaines personnes ne comprendront probablement pas ce que je veux dire, alors je vais clarifier mon propos :
je pense que les tests unitaires sont une excellente chose, et je regrette énormément de ne pas avoir de tests
unitaires pour mon jeu. Je veux dire que j’ai écrit mon jeu de la manière dont la plupart des programmeurs
expérimentés vous diraient d’écrire ce genre de système, et que c’est maintenant une base de code
épouvantablement ingérable. Si j’avais fait "comme il se doit" des tests unitaires, il serait deux fois plus
épouvantable ! Le paradoxe qui apparaît ici est crucial pour comprendre pourquoi j’ai cette opinion
minoritaire à propos de la taille des bases de code.
Il n’est jamais arrivé quelque chose de vraiment mal à la plupart des programmeurs. Dans les rares cas où
quelque chose de mal arrive, ils ne s’aperçoivent généralement pas qu’il s’agit d’un
problème, pas plus que dans le BTP un travailleur ne voit la boue comme un problème. C’est seulement qu’il
y a partout une certaine quantité de boue, et que vous devez faire avec : ce n’est pas "mal", c’est
juste un défi tactique.
Beaucoup d’entreprises sont face à de nombreux millions de lignes de code, et elles le voient comme un simple
problème d’outillage, rien de plus : beaucoup de boue qu’il faut déplacer de temps en temps.
La plupart des gens n’ont jamais eu à maintenir une base de code d’un demi-million de lignes à la fois,
leur vision des choses sera probablement différente de la mienne. Heureusement vous, étant le jeune individu
impatient d’apprendre que vous êtes, allez réaliser que les seules personnes vraiment qualifiées pour exprimer
une opinion sur ce sujet sont celles qui ont vécu avec (et aidé à créer) des bases de code vraiment énormes.
Vous pourriez entendre des hurlements en réponse à ma petite déclaration d’aujourd’hui, et beaucoup de "c’est
simplement qu’il ne comprend pas". Mais j’affirme que ceux qui font ce genre d’affirmations n’ont
simplement jamais été tenus responsables du désordre qu’ils ont créé.
Quand vous écrivez votre propre base de code d’un demi-million de lignes, vous ne pouvez pas échapper à vos
responsabilités. Je n’ai personne à blâmer à part moi-même, et cela m’a donné une perspective qui m’a
rangé dans cette catégorie minoritaire.
Ce n’est pas non plus seulement à cause de mon jeu. Cela seul n’aurait pas suffit à m’apprendre la
leçon. Dans mes vingt ans passés dans ce domaine, j’ai probablement eu affaire à certaines des plus grandes
bases de code que vous avez jamais imaginées, et j’ai ainsi appris certaines choses que la plupart des gens
n’apprennent jamais de toute leur carrière. Je ne vous demande pas de changer d’avis sur le
sujet aujourd’hui. J’espère seulement que vous garderez vos yeux et vos oreilles ouvertes lorsque vous
coderez pendant les prochaines années qui viennent.
Bourrelets invisibles
Je vais essayer ici de définir bouffi. Je sais à l’avancer que je vais échouer, mais heureusement esquisser le
problème suffira à vous faire comprendre certains modèles.
Certaines des choses qui peuvent mal se passer avec des bases de codes sont intuitives au point qu’il n’est
pas difficile pour la plupart des gens d’être d’accord qu’elles sont "mauvaises".
L’une de ces choses est la complexité. Personne n’aime les bases de codes complexes. Une des mesures de
la complexité parfois utilisée est la "complexité cyclomatique", qui estime les chemins d’exécution possibles
à travers une fonction donnée en utilisant une analyse statique simple de la structure du code.
Je suis assez sûr que je n’aime pas les bases de code complexes, mais je ne suis pas convaincu que les mesures
de complexité cyclomatiques y ont contribué. Pour avoir un bon taux de complexité cyclomatique, vous devez séparer
votre code en fonctions plus petites. Séparer votre code en fonctions plus petites est un gage de "bonne conception"
depuis maintenant au moins dix ans, pour une part non négligeable ceci est dû au livre Refactoring [5]
de Martin Fowler.
Le problème avec le refactoring tel qu’il s’applique aux langages comme Java, et c’est un élément
vraiment central de ma thèse d’aujourd’hui, est que le refactoring fait grandir la base de code. J’estime
que moins de 5% des refactoring standards offerts par les IDEs aujourd’hui diminuent la taille du code.
Refactorer c’est comme de ranger votre placard sans avoir le droit de rien jeter. Si vous prenez un placard
plus grand, et rangez tout dans de belles boites étiquetées, alors votre armoire sera indubitablement mieux
organisée. Mais les programmeurs ont tendance à passer à côté du fait que le nettoyage de printemps fonctionne mieux
quand vous êtes prêt à vous débarrasser des choses inutiles.
Ce qui nous amène à la deuxième chose mauvaise de manière évidente qui peut arriver avec les bases de code : le
copier-coller. Les programmeurs ne mettent pas longtemps à apprendre cette leçon à la dure. Ce n’est pas tant
une règle que vous devez apprendre qu’une cicatrice que vous aurez que vous le vouliez ou non. Les ordinateurs
rendent le copier-coller vraiment simple donc tous les programmeurs tombent dans le piège de temps en temps.
La leçon que vous apprendrez peut-être est que le code change toujours, toujours toujours toujours, et chaque fois
que vous devez modifier la même chose à N endroits, où N est plus grand que 1, vous avez gagné votre cicatrice.
Par ailleurs, le copier-coller est bien plus insidieux que ne le suspectera jamais le plus timoré des programmeurs.
La base du problème est la duplication, et malheureusement il y a des modèles de duplication qui ne peuvent
être éradiqués du code Java. En Java, ces modèles de duplication sont partout, ils sont omniprésents, mais les
programmeurs Java deviennent rapidement complètement incapables de les remarquer.
Les programmeurs Java se demandent souvent pourquoi Martin Fowler a "quitté" Java pour Ruby. Bien que je ne connaisse
pas Martin, je pense qu’on peut faire l’hypothèse probable que "quelque chose de mal" lui est arrivé en
utilisant Java. De manière amusante (pour tout le monde sauf peut-être Martin lui-même), je pense que ce quelque
chose de mal a bien pu être l’acte d’écrire le livre Refactoring, qui a montré aux programmeurs
Java comment rendre leurs armoires plus grandes et mieux organisées, tout en montrant à Martin que ce qu’il
voulait vraiment était de mettre plus de choses dans une belle et confortable armoire de la taille d’une
armoire.
Martin, est-ce-que je me trompe ?
Comme je le prévoyais, je n’ai pas encore défini déborder sauf dans les termes les plus vagues. Pourquoi
est-ce-que le code de mon jeu fait un demi-million de lignes de code ? Que fait tout ce code ?
Les Design Pattern ne sont pas des fonctionnalités
L’autre livre primordial dans le domaine de la conception a été Design Patterns qui a laissé une empreinte
visible sur les visages de tous les programmeurs du monde, dans l’hypothèse où le monde contienne seulement
des programmeurs Java et C++, hypothèse qu’ils font souvent.
Design Patterns est un livre du milieu des années 1990 qui fournit vingt-trois nouvelles boites fantaisies pour
organiser votre placard, plus un mécanisme d’extensibilité pour définir de nouveaux types de boites. C’était
vraiment une bonne chose pour ceux d’entre nous qui essayaient d’organiser des placards pleins à craquer
sans presque aucune boite, sac, étagère ou tiroir. Tout ce que nous avions à faire c’était reconstruire nos
maisons pour que les placards soient quatre fois plus grands, et soudain ils pouvaient être aussi bien rangés qu’un
rayon de chez Leclerc.
Il est intéressant de remarquer que les commerciaux n’ont pas été enthousiasmés par les Design Patterns. Ni les
chefs de projet, ni les gens du marketing, ni même les responsables d’ingénierie. Les seules personnes qui
sont généralement enthousiasmées par les Design Patterns sont les programmeurs, et seulement ceux qui utilisent
certains langages. Les programmeurs Perl n’ont pas été, pour la plupart, impressionnés par les Design
Patterns. Mais les programmeurs Java ont mal interprété cela, ils en ont conclu que les programmeurs Perl doivent
être bordéliques, de mauvais célibataires qui empilent leurs linge dans leurs placards du bas jusqu’en
haut.
C’est pourtant évident maintenant, n’est-ce-pas ? Un design pattern n’est pas une
fonctionnalité. Une Factory [6]
n’est pas une fonctionnalité, ni une délégation ni un proxy ni un pont. Ils "offrent" des fonctionnalités dans
un sens très lâche, en fournissant des jolies boites pour contenir les fonctionnalités. Mais les boites les sacs et
les étagères prennent de la place. Et les design patterns – au moins la plupart des pattern dans le livre du
"gang des quatre" [7] – font
grossir la base de code. Tragiquement, le seul modèle du gang des quatre qui peut aider à diminuer le code (l’interpréteur)
est totalement ignoré par les développeurs qui sinon ont les noms des Design Patterns tatoués en divers endroits du
corps.
L’injection de dépendance est un exemple de nouveau design pattern Java populaire dont les programmeurs qui
utilisent Ruby, Python, Perl et JavaScript n’ont probablement jamais entendu parler. Et s’ils en ont
entendu parler, ils ont probablement (et justement) conclu qu’ils n’en ont pas besoin. L’injection
de dépendance est une infrastructure étonnamment élaborée qui permet de rendre Java plus dynamique d’une
manière qui est naturelle dans les langages de plus haut niveau. Et – vous l’avez deviné – il fait
grandir votre base de code.
"Plus grand" est quelque chose avec lequel vous devez vivre en Java. Grossir est une loi naturelle. Le Java est une
variante du jeu Tetris dans lequel aucune des pièces ne peut remplir les trous créés par les autres pièces, donc la
seule chose que vous pouvez faire c’est les empiler indéfiniment.
Des millions de lignes de code
J’ai récemment eu l’opportunité de voir un programmeur Java autodidacte faire une présentation dont une
des fiches donnait la liste des Problèmes (de son système Java actuel) et un autre fiche les Besoins (du merveilleux
système qui ne verra jamais le jour). Le problème n°1 qu’il a cité était la taille du code : son
système faisait plusieurs millions de lignes de code.
Waou ! J’ai sûrement déjà vu ça, et je pourrais vraiment compatir avec lui. Geoworks avait bien
plus de dix millions de lignes de code assembleur [8], et je suis d’avis que cela les a
aidés à faire faillite (bien que cela soit une opinion minoritaire – ces programmeurs n’apprennent jamais !).
Et j’ai travaillé pour Amazon pendant sept ans ; ils ont bien plus d’une centaine de millions de
lignes de code dans divers langages, et la "complexité" est souvent citée en interne comme leur plus gros problème
technique.
Donc j’étais vraiment content de voir que cette personne ait dit que la taille du code était son problème n°1.
C’est alors que j’ai été surpris. Quand il est passé à sa fiche avec les Besoins, et qu’il a cité
"doit pouvoir grandir jusqu’à plusieurs millions lignes de code" comme un besoin. Tout le monde dans la
salle à part moi a hoché la tête et a accepté cette demande. J’étais ébahi.
Mais pourquoi diable votre problème n°1 fait-il partie des besoin du nouveau système ? Je veux dire que,
quand vous faites la liste de vos besoins, vous essayez généralement de résoudre les problèmes plutôt que de
supposer qu’ils seront créés à nouveau. J’ai donc interrompu l’orateur et je lui ai demandé à quoi
il pouvait bien penser.
Sa réponse fut : et bien, ce système a de nombreuses fonctionnalités, et plus de fonctionnalités signifie plus
de code, donc des millions de lignes de code sont Simplement Inévitables. "Ce n’est pas que Java est verbeux !"
ajouta-t-il — ce qui par ailleurs est plutôt amusant, toutes choses considérées, vu que je n’avais rien dit à
propos de Java ou de la verbosité dans ma question.
Il faut signaler que, si en lisant cette histoire vous avez été stupéfié et vous êtes dit "comment ce javaïste
peut-il être aussi aveugle ?", vous faites officiellement partie d’une minorité dans le monde de
la programmation. Une minorité mal accueillie, en plus.
La plupart des programmeurs ont réussi à compartimenter leurs croyances à propos de la taille des bases de code. Les
programmeurs Java sont particulièrement atteints mais ils ne sont en aucune façon les seuls. Dans un compartiment,
ils savent que les grandes bases de code sont mauvaises. Des connaissances arithmétiques du niveau d’un
écolier suffisent à prendre conscience d’à quel point cela peut être mauvais. Si vous avez un million de
lignes de code, avec 50 lignes par "page", cela représente 20.000 pages de code. Combien de temps cela vous
prendrait-il pour lire un manuel d’utilisation de 20.000 pages ? Le simple effort de parcourir la base de
code et d’essayer d’en saisir la structure générale pourrait vous prendre des semaines ou même des mois,
suivant sa densité. Des changements architecturaux significatifs pourraient prendre des mois ou même des années.
Dans l’autre compartiment, ils pensent que leurs IDEs font en sorte que la taille du code ne soit pas un
problème. Nous allons en parler bientôt.
Et un million de lignes de code ce n’est rien, vraiment. La plupart des entreprises aimeraient avoir
seulement un million de lignes de code. Souvent une seule équipe peut dépasser ce chiffre en quelques années de
codage. De nos jours, les grands entreprises doivent se débrouiller avec des dizaines ou des centaines de millions
de lignes de code.
Je vais vous donner la quintessence, le résumé en une phrase de ce que j’ai appris de la Mauvaise Chose qui m’est
arrivée pendant que j’écrivais mon jeu en Java : si vous commencez par l’hypothèse que vous devez
diminuer votre base de code, vous serez probablement forcé de conclure que vous ne pouvez pas continuer à
utiliser Java. À l’inverse, si vous commencez par l’hypothèse que vous devez utiliser Java, vous serez
probablement forcé de conclure que vous aurez des millions de lignes de code.
Est-ce-que le compromis en vaut la peine ? Les programmeurs Java vous diront que Oui, cela en vaut la peine. En
agissant ainsi ils acquiescent tacitement au petit compartiment qui réalise que les grandes bases de code sont
mauvaises, donc vous aurez au moins gagné cette bataille.
Mais vous devriez prendre tout ce qu’un "programmeur Java" vous dit avec un gros grain de sel, parce qu’un
"programmeur X", pour n’importe quelle valeur de X est un petit joueur. Vous devez maîtriser plusieurs
disciplines pour être un athlète décent de nos jours. Les programmeurs doivent être à l’aise dans de multiples
langages avec des "caractères" fondamentalement différents avant d’être capables de prendre des décisions de
conception vraiment fondées.
Récemment, j’ai découvert que Java est une valeur particulièrement mauvaise pour X. Si vous devez
absolument engager un programmeur X, soyez certain qu’il s’agit de Y.
Je ne voulais pas vraiment focaliser ce texte sur Java (et les clones de Java comme le C#, qui même s’il sont
maintenant un "meilleur" langage, ont toujours le caractère fondamental de Java, ce qui fait qu’il n’est
au mieux qu’une amélioration marginale). Pour être certain, mon opinion minoritaire s’applique à n’importe
quelle base de code dans n’importe quel langage. Le code bouffi est mal.
Mais il se trouve que je me suis focalisé sur Java parce que j’ai cette base de code éléphantesque que j’essaie
de faire revivre cette semaine. Pouvez-vous me blâmer ? Heureusement quelqu’un avec un éléphant de
compagnie en C++ peut me rejoindre et venir soutenir l’opinion minoritaire avec moi. Pour le moment, je vais
essayer de terminer mon explication sur le code bouffi comme un problème de bonne foi en utilisant Java comme
contexte.
Les IDEs peuvent ils vous sauver ?
La communauté Java croit, avec un Taux de Croyance de presque 100%, que les IDEs modernes feront en sorte que la
taille des bases de code ne soit pas un problème. Fin de l’histoire.
Il y a plusieurs problèmes avec ce point de vue. Le premier tient à nouveau de la simple arithmétique : avec une
quantité de code suffisante, vous n’aurez pas suffisamment de ressource machine pour gérer le code. Imaginez
un projet avec un milliard de lignes de code, et imaginez ensuite d’essayer d’utiliser Eclipse ou
IntelliJ sur ce projet. Les machines - processeur, mémoire, disque, réseau - ne seraient simplement pas suffisantes.
Nous le savons parce que des bases de code de vingt millions de lignes sont déjà hors de portée des IDEs modernes
sur des machines modernes.
Flûte, je n’ai jamais réussi à faire en sorte qu’Eclipse prenne en compte et indexe même ma base de code
de 500.000 lignes, et j’ai passé des semaines à essayer. Il se contente d’échouer, paralysé. Il s’arrête
littéralement (je peux le laisser toute une nuit sans que ça ne change rien). Vingt millions de lignes ?
Oubliez ça.
Il devrait être possible d’atténuer le problème en déplaçant la gestion de la base de code d’une machine
locale à des groupes de serveurs. Mais le problème central est vraiment plus culturel que technique : aussi
longtemps que les utilisateurs d’IDEs refuseront d’admettre qu’il y a un problème, il ne sera pas
résolu.
Revenons à notre folle partie de Tétris, imaginez que vous ayez un outil qui vous permette de gérer de gigantesques
écrans de Tétris qui font des centaines de lignes de haut ? Dans ce scénario, empiler les pièces n’est
pas un problème, donc il n’y a pas besoin d’être capable d’éliminer les pièces. Le problème
culturel est là : ils ne réalisent pas qu’ils ne sont plus en train de jouer au bon jeu.
La deuxième difficulté avec le point de vue des IDEs est que les IDEs du style Java créent intrinsèquement un
problème circulaire. La circularité provient de la nature des langages de programmation : les formes des
"pièces du jeu" sont déterminées par le système de typage statique du langage. Les pièces du jeu Java ne permettent
pas d’éliminer du code parce que le système de typage statique de Java n’a aucune fonctionnalité
permettant de réduire le code – pas de macros, pas de lambdas, pas de structures de données déclaratives, pas
de modèles, rien qui permettrait la suppression des modèles nécessitant des copier-coller que les programmeurs Java
voient comme un "bruit de fond inévitable", mais qui sont facilement regroupés dans un langage dynamique.
Fermant le cercle, les fonctionnalités dynamiques rendent plus difficile aux IDEs de mettre en œuvre leur gestion
magique de bases de code. les IDEs ne fonctionnent pas aussi bien avec les fonctionnalités de code dynamiques, donc
les IDEs sont responsables d’encourager l’utilisation des langages qui nécessitent … des IDEs,
Aïe.
À un certain niveau, les programmeurs Java le comprennent : par exemple, la capacité populaire de réflexion de
Java, qui vous permet de construire des noms de méthode à la volée puis de les invoquer par leur nom, empêche les
IDEs de mettre en œuvre les refactorings simples comme de renommer une méthode. Mais à cause de la
compartimentalisation réussie, les javaïstes montrent du doigt les langages dynamiques et hurlent que (certains)
refactorings automatisés ne sont pas possibles, alors qu’ils sont seulement aussi possibles dans ces langages
qu’en Java, ce qui veut dire qu’ils sont partiellement possibles. Les refactorings vont "échouer" quand
vous utilisez les fonctionalités dynamiques, que vous écriviez du Java ou n’importe quel autre langage. Par
essence, les refactoring ne sont jamais 100% efficaces, spécialement quand la base de code est utilisée à l’extérieur
avec des APIs publiques : c’est précisément pour cela que Java possède la dépréciation. Vous ne pouvez
pas renommer une méthode sur toutes les machines du monde. Mais les javaïstes continuent de propager la croyance
probablement fausse que le refactoring automatique fonctionne sur "tout" leur code.
Je vais parier que vous êtes en ce moment aussi content que moi que nous ne soyons pas en train de parler à des
programmeurs Java ! Maintenant que j’ai démontré une des (nombreuses) manières dont ils sont clairement
irrationnels, il devrait être plutôt clair que leurs réponses ont peu de chances d’êtres rationnelles.
Taille de code rationnelle
La réponse rationnelle devrait être de faire un très grand pas en arrière, de stopper tout le développement, et de
poser une question difficile : "que devrais-je utiliser à la place de Java ?"
Je l’ai fait il y à peu près quatre ans. C’est à ce moment là que j’ai arrêté de travailler sur mon
jeu, pour le mettre en mode maintenance. J’ai voulu le réécrire en 100.000 à 150.000 lignes, quelque chose de
cet ordre-là, avec exactement les mêmes fonctionalités.
Il m’a fallu six mois pour réaliser que cela ne pouvait être fait avec Java, pas même avec les choses qu’ils
ont ajouté à Java 5, et même avec les choses qu’ils prévoyaient d’ajouter pour Java 7 (même s’ils
ajoutent les choses sympas, comme les closures qui fonctionnent, contre lesquelles la communauté Java résiste becs
et ongles).
Ça ne peut pas être fait avec Java. Mais j’avais beaucoup investi dans la machine virtuelle Java,
fondamentalement pour la même raison qui explique pour moi le gros investissement de Microsoft dans la machine
virtuelle .NET. Je veux dire "explique" à un niveau superficiel, quand je lis les brochures marketing, mais
maintenant que j’ai écrit quelques interpréteurs et que j’ai fait mon chemin dans des compilateurs en
code natif, ça s’explique beaucoup mieux. Mais c’est une autre histoire, malheureusement.
Donc étant donné qu’aujourd’hui les machines virtuelles sont "bonnes", et en acceptant que mon jeu est
assez lourdement lié à la machine virtuelle Java (JVM) – pas seulement les grandes bibliothèques et les outils de
surveillance, mais aussi pour des décisions architecturales plus subtiles comme le modèle d’exécution et de
mémoire – la réponse rationnelle au code bouffi est d’utiliser un autre langage de la JVM.
Une bonne chose à propos des langages de la JVM est que les programmeurs Java peuvent les apprendre assez vite, parce
que vous avez toutes les bibliothèques, outils de surveillance et décisions architecturales pour rien. Le revers de
la médaille est que la plupart des programmeurs Java sont des programmeurs X, et, comme je l’ai dit, vous ne
voulez pas de programmeurs X dans votre équipe.
Mais comme vous n’êtes pas de ceux qui ont décidé de porter des pantalons pattes d’éléphant en polyester
jusqu’au jour de votre mort, dussiez vous vivre cinq cents ans, on peut vous suggérer des langages. C’est
une bonne chose pour vous !
Il y a trois ans, j’ai décidé de choisir le langage de la JVM qui serait le meilleur réducteur de code pour
succéder à Java. Cela a pris beaucoup plus longtemps que je ne le pensais, et la réponse a été bien moins
satisfaisante que je le prévoyais. Même maintenant, trois ans après, la réponse est toujours à un ou deux ans d’être
vraiment satisfaisante.
Je suis patient maintenant, donc après que toute la poussière se soit déposée, je sais que j’ai une fenêtre d’à
peu près deux ans pendant laquelle les programmeurs Java extrémistes d’aujourd’hui sont en train d’écrire
leur prochain désastre de plusieurs millions de lignes. Au moment où ils feront leur prochaines fiches de
Problèmes/Besoins je pense que j’aurai une réponse pour eux.
Dans l’intervalle, j’espère trouver le temps de réécrire mon jeu dans ce langage, en le réduisant de
500.000 à 150.000 lignes avec exactement les même fonctionnalités (plus au moins 50.000 lignes pour les tests
unitaires).
Le prochain Java
Donc quel langage de la JVM sera-t-il le prochain Java ?
Hé bien, si vous vous placez du seul point de vue de la diminution du code, vous voudrez vraiment un dialecte Lisp :
Common Lisp ou Scheme. Et de très bonnes implémentation Java existent. Je les ai utilisées. Malheureusement, un
langage JVM doit pouvoir directement remplacer Java (ou alors une migration va être un vrai problème logistique), et
cela ne semble une priorité pour aucune des implémentations de Lisp/Scheme.
En plus, tout le monde vous crachera dessus. Les personne qui habituellement ne crachent pas, expectoreront jusqu’à
vingt mètres, comme les chameaux du zoo, pour vous atteindre si seulement vous suggérez la possibilité d’utiliser
un dialecte Lisp ou Scheme dans votre entreprise.
Donc ça ne sera pas Lisp ou Scheme. Nous allons devoir sacrifier un peu de compression pour quelque chose d’un
peu plus syntaxiquement courant.
Cela pourrait théoriquement être Perl 6, en supposant que les développeurs de Parrot arrivent jamais à quelque chose
qui fonctionne, mais si vous voulez mon avis, ils sont encore plus patients que moi. Perl 6 est vraiment un beau
langage, pour mémoire – je m’en suis vraiment entiché en 2001. Mais l’amourette s’est terminée il
y a cinq ans. Et Perl 6 ne s’exécutera probablement jamais dans la JVM. Il est trop dépendant des
puissantes fonctionalités de Parrot que la JVM n’offrira jamais. (Je m’aventurerai même à dire que
Parrot ne les offrira jamais non plus, mais ça serait méchant.)
Le plus probable est que le nouveau Java sera un langage déjà suffisamment populaire avec une très bonne version
fonctionnant dans la JVM. Ce sera un langage avec une équipe de développement dédiée et un bon département
marketing.
Cela réduit les possibilités de plus de 200 langages à peut-être trois ou quatre : JRuby, Groovy, Rhino
(Javascript) et peut-être Jython s’il sort de son coma.
Chacun de ces langages (comme Perl 6) offre des mécanismes qui permettraient de réduire une base de code Java bien
conçue de 500.000 lignes de code de 50 à 75%. Le chiffre exact (entre 50 et 75%) doit encore être déterminé, mais je
vais essayer moi-même.
J’ai personnellement essayé Groovy et j’ai trouvé qu’il s’agissait d’un langage hideux
avec une poignée d’idées valables. Il veut être Ruby mais n’a pas son élégance (ou de Python pour ce
domaine). Il existe depuis longtemps et sa popularité n’a pas l’air de croître, donc je l’ai
éliminé pour mon propre travail. (Et c’est définitif – je ne m’y intéresserai plus. Des
problèmes d’implémentation de Groovy m’ont vraiment dégoûté.)
J’aime beaucoup Ruby et Python, mais aucune des deux implémentations Java n’était à la hauteur quand j’ai
fait mon évaluation il y a trois ans. Beaucoup de travail a été fait sur JRuby entre temps. Si les personnes
avec lesquelles je travaille n’étaient pas aussi remontées contre Ruby, cela serait probablement mon choix, en
priant que l’implémentation soit "suffisamment rapide" par rapport à Java.
Ce qui s’est finalement passé, c’est que j’ai choisi Rhino. Je vais travailler avec l’équipe
de Rhino pour qu’il respecte les spécifications EcmaScript
Édition 4. Je pense que ES4 amène grosso-modo Javascript au niveau de Ruby et Python en terme de (a)
expressivité et (b) capacité de structurer et gérer des bases de code plus grandes. Toutes les friandises qui lui
manquent sont compensées par ses annotations optionnelles de typage. Et je pense que JavaScript (particulièrement
avec les fonctionalités de ES4) est plus facile à vendre que Ruby et Python pour les personnes qui aiment les
accolades, ce qui veut dire tous ceux qui utilisent actuellement C++, Java, C#, JavaScript ou Perl. Ça fait un sacré
nombre d’amoureux des accolades. Je suis un vrai pragmatique en ce moment.
Je n’espère pas que ma petite déclaration d’aujourd’hui convainque qui que ce soit de
partager mon opinion minoritaire à propos de la taille des bases de code. Je sais qu’un certain nombre de
personnes (Bill Gates, par exemple, et aussi Dave Thomas, Martin Fowler et James Duncan Davidson) ont chacun de leur
côté atteint la même conclusion : à savoir qu’un code bouffi est la pire chose qui puisse arriver. Mais
pour en arriver là ils ont tous subi des choses douloureuses.
Je ne peux pas espérer qu’une chose douloureuse arrive aux développeurs Java, puisque hey, c’est déjà en
train de se passer ; ils ont déjà appris à prétendre que ça ne leur fait pas mal.
Mais dans votre cas, le jeune étudiant ou lycéen impatient qui veut devenir un jour un excellent programmeur, je vous
ai heureusement donné une chose de plus à surveiller quand vous vous occuperez de votre code pour les prochaines
années.
Quand vous serez prêt à faire le changement, hé bien, Mozilla
Rhino sera prêt pour vous. Il fonctionne bien aujourd’hui et sera absolument génial dans un an. Et j’espère
sincèrement que JRuby, Jython et d’autres seront aussi des alternatives viables à Java. Vous pouvez même les
essayer maintenant et voir ce que cela donne.
Votre base de code vous en remerciera.
[1] n.d.t. : le code informatique
qui constitue le jeu
[2] n.d.t. : informatique
[3] n.d.t. : Integrated Development
Environment = Environnement de Développement Intégré : programme permettant de faire l’intégralité du
développement informatique
[4] n.d.t. : tests automatisées qui
permettent de valider les différentes parties du code indépendamment les unes des autres
[5] n.d.t. : "reconstruction" en
français
[6] n.d.t. : un Design pattern qui
sert à créer des objets
[7] n.d.t. : surnom habituel des
quatre auteurs du livre
[8] n.d.t. : langage qui est celui
avec lequel fonctionne un ordinateur, à opposer aux langages de plus haut niveau qui doivent être transformés en
assembleur pour fonctionner
Une traduction (assez littérale) d’un article de Charles Miller.. Cette traduction est disponible sous la licence Creative-Commons
Paternité-Pas d’Utilisation Commerciale-Pas de Modification.
Dans un message sur le blog interne d’Atlassian [1], j’ai décrit comme "très
difficile" un certain problème pour expliquer pourquoi nos efforts seraient mieux investis ailleurs. Plus tard,
alors que je traversais le pont pour me rendre au travail, j’ai pris un moment pour examiner cette formule
du point de vue d’un non-ingénieur. Atlassian s’enorgueillit d’embaucher des personnes
vraiment brillantes. À quoi servent-elles si elles ne peuvent résoudre des problèmes difficiles ?
Pour le comprendre, voici un petit lexique de ce que les ingénieurs informatiques veulent généralement dire quand
ils parlent de la difficulté d’un problème, en commençant par le cas le plus extrême :
Impossible
L’homme le plus communément considéré comme le "père" de la science informatique est le mathématicien
anglais Alan Turing.
Turing a beaucoup travaillé pendant la Deuxième Guerre Mondiale pour aider les Alliés à casser les codes de
cryptage militaire allemands. Pour le récompenser après la guerre, le gouvernement anglais l’a reconnu
coupable d’indécence grave (il était homosexuel), lui a retiré son habilitation de sécurité et l’a
soumis à un traitement hormonal. Sa mort peu de temps après est généralement considérée comme un suicide.
Peu importe. La plus célèbre contribution de Turing à la science informatique est la thèse de
Church-Turing. Elle décrit un appareil théorique appelé Machine Universelle de Turing qui est capable
à la fois de résoudre tout problème calculatoire pouvant être représenté par un algorithme et de remplacer
tout autre appareil résolvant des problèmes calculatoires.
Tout ce qui peut être calculé mécaniquement (de manière déterministe) peut être calculé par une machine de
Turing. Tout appareil qui réalise des calculs mécaniques déterministes n’est en réalité qu’une
machine de Turing. Les ingénieurs disent d’un matériel informatique ou d’un langage de programmation
qui possède l’intégralité de cette capacité de calcul qu’il est "complet au sens de Turing".
Dans ce cadre, le mot "impossible" a un sens bien définit. Un problème est impossible si sa solution ne peut
pas être déterminée par une machine de Turing.
Il faut reconnaître que cette distinction n’est pas très utile. D’un côté, les machines de Turing
sont une théorie mathématique. Elles sont infiniment rapide et on une capacité de stockage illimitée, et vous
avez autant de temps que nécessaire pour écrire vos programmes. Ainsi, beaucoup de choses possibles en théorie
sont impossibles dans la pratique (je reviendrai plus loin sur ce sujet).
D’un autre côté, dans ce cadre (et les ingénieurs trébuchent sur ce point en permanence), avoir presque
la réponse à un problème n’a aucune valeur. Aucune machine de Turing ne vous dira si vous allez aimer ou
non un livre, mais Amazon gagne beaucoup d’argent en ayant une réponse suffisamment juste.
Trivial
À l’autre bout de l’échelle, nous avons les problèmes qui sont triviaux. Cetet définition peut être
exprimée en bien moins de mots :
Je sais comment résoudre ce problème
Pour un programmeur, un problème est trivial s’il y a une solution claire, et que la chose qui doit être
faite est de la mettre en œuvre.
Le seul soucis est que la trivialité se réfère à la difficulté de résolution du problème, et pas à la
difficulté de mettre en œuvre la solution. Ainsi il n’y aucune relation entre le fait pour un problème d’être
trivial et le temps qu’il faut pour le résoudre. Pour un programmeur, une fois que les plans d’un
pont sont établis, les matériaux bien choisis et qu’on a testés comment le modèle survivrait aux vents, au
trafic et aux tremblements de terre, construire réellement le pont est trivial.
Insoluble [2]
Un problème est insoluble si on connaît une partie suffisante de la solution pour déterminer que vous n’avez
pas les ressources pour le résoudre. Vous pouvez ne pas avoir assez de développeurs ou d’expertise
disponibles, ou cela nécessite peut-être seulement plus de matériel que vos moyens ne le permettront jamais.
Le domaine de la cryptographie nous offre un exemple parfait d’un problème à la fois trivial et insoluble.
Les algorithmes [3]
qui cryptent
et décryptent les données sont bien connus et publiés. En supposant que les algorithmes fonctionnent "comme
promis", pour décrypter une donnée vous devez seulement écrire le programme qui met en œuvre cette algorithme,
et employer assez de matériel de calcul pour exécuter cet algorithme avec toutes les clés possibles.
La cryptographie fonctionne en choisissant des clés d’une manière qui assure qu’il n’y ait pas
suffisamment de matériel de calcul disponible, pour qu’en pratique
un tel programme se termine jamais. Décrypter une telle donnée est un problème insoluble.
Non-trivial
Un ex non-ingénieur de chez Google décrivait ainsi "non-trivial" sur le blog Xooglers :
Cela signifie impossible. Vu qu’aucun ingénieur n’admettrait que quelque chose est impossible,
ils utilisent ce mot à la place. Un ingénieur qui affirme que quelque chose est "non-trivial" équivaut à un
pilote de ligne vous annonçant calmement que vous pourriez subir "juste quelques turbulences" alors qu’il
va vous faire traverser un ouragan de force 5.
Cette citation vous montre la différence de conception de la non-trivialité entre un ingénieur et un
non-ingénieur, et leur différence de conception d’impossible (Voler à travers un ouragan n’est
pas nécessairement impossible, c’est juste que vous n’avez vraiment pas envie de le faire).
Par opposition claire au sens de trivial, non-trivial signifie :
Je ne sais pas comment résoudre complètement ce problème.
Les problèmes non-triviaux contiennent de dangereuses inconnues. Certaines parties d’entre elles ne sont
pas encore comprises, ou sont au-delà des choses que le programmeur a déjà réalisées, ou des choses pour
lesquelles il peut imaginer rapidement une solution qui fonctionne. Plus le développeur qui vous dit qu’un
problème est non-trivial est expérimenté, plus vous devriez prendre cela en compte.
Avec du temps pour des recherches et des essais, un problème non-trivial peut être rendu trivial. Où on peut
déterminer qu’il est difficile.
Difficile, et très difficile
Les problèmes difficiles sont un type de problème non-triviaux [4] dont une partie des
inconnues, i.e. les problèmes dont l’ingénieur devrait réussir à s’occuper, sont connues pour
être difficiles à résoudre. Ce sont des problèmes qu’il a essayé de résoudre dans le passé, ou dont il a
vu les ressources que d’autres ingénieurs ont dû investir pour tenter de résoudre des problèmes
similaires.
"Difficile" peut aussi être utilisé pour décrire des problèmes non-triviaux qui ont une chance importante de
contenir des "inconnues inconnues" – des choses dont non seulement le développeur ne connaît pas la
solution, mais dont en plus il ne connaît même pas l’existence.
Augmenter la capacité d’une application web est difficile. Il y a plusieurs problèmes épineux à résoudre
avec la performance, la distribution, l’accès aux données, le cache et ainsi de suite qui vont demander
pas mal d’efforts, et il y a souvent suffisamment de différences d’une application à l’autre
pour qu’il n’y ai pas de bonne solution générale. Il y a aussi les inévitables problèmes épineux que
vous n’avez même pas anticipés, qui se cachent dans les coins.
"Très Difficile" est l’extrême des problèmes difficiles. Vous verrez souvent ces deux mots mis en majuscule
pour les mettre en valeur, même au milieu d’une phrase. Indexer le web et fournir des réponses pertinentes
à des requêtes avec un temps de réponse de quelques millisecondes est un problème Très Difficile. Casser un
cryptage de qualité commerciale avec un matériel réaliste et dans une limite de temps est un problème Très
Difficile. La paix au Moyen-Orient est un problème Très Difficile.
"Très Difficile" est généralement réservé au type de problèmes grâce auxquels, si vous les avez résolus, vous
pouvez changer le monde. Ou au moins vous en servir pour créer une affaire profitable.
[1] n.d.t. la société où travaille l’auteur
[2] (n.d.t. la note s’applique
à la version américaine) Quand j’ai mis ce texte en ligne pour la première fois, j’ai mentionné en
passant que le terme correct était ’non soluble’ (n.d.t. ’not feasible’). Des recherches
plus approfondies indiquent qu’insoluble (n.d.t. ’unfeasible’) est aussi d’usage
courant, mais la grande majorité des emails ont été dans le sens d’insoluble’. Ne jamais utiliser un
seul dictionnaire américain comme source.
[3] n.d.t. un algorithme est une
suite d’instruction
[4] Gary Capell m’a indiqué
dans un email que, dans le langage classique de l’ingénierie, les problèmes difficiles, ou même Très
Difficiles, peuvent quelquefois être appelés ’distinctement non-triviaux’.