Des traductions


Métayage et longue traîne

Une traduction d’un article de Nicholas Carr : Sharecropping the long tail (métayage et longue traîne).

Il y a peu, j’ai écrit que le Web 2.0, en mettant les moyens de production dans les mains des masses mais en refusant à ces mêmes masses tout droit de propriété sur le produit de leur travail, fournit un mécanisme incroyablement efficace pour récupérer la valeur économique du travail gratuit fourni par le plus grand nombre et le concentrer dans le mains de quelques-uns.

Les nouvelles analyses des modèles de trafic du web de Richard MacManus aident à illustrer ce point. Malgré l’explosion du contenu du web, aiguillonné principalement par la réduction du coût de la production et de la consommation de ce contenu, le trafic web semble s’accroître en se concentrant sur un nombre de sites plus faible. En utilisant des données de Compete, MacManus montre que les dix sites les plus consultés constituaient 40% du total des pages vues sur internet en novembre 2006 contre 31% en novembre 2001, soit une augmentation de 29%. Cette augmentation de la concentration se produisant alors même que le nombre de domaines sur le web était quasiment multiplié par deux, passant de 2,9 à 5,1 millions.

Même si on considère que les données de trafic ne sont pas fiables et que compter les pages consultées n’est pas la seule manière de mesurer le trafic, la tendance semble claire : quelques gros sites dominent progressivement le web.

Á première vue, cela semble contredire la théorie de la longue traîne ou des lois de puissance. Mais ce n’est pas si simple. Comme le montre MacManus, la concentration de trafic plus importante peut être expliquée largement par la popularité de deux sites de "réseau social", MySpace et Facebook, qui constituent à eux deux 17% de toutes les pages consultées en novembre 2006. MySpace et Facebook sont tous deux constitués de millions de "profils utilisateurs" créés par leurs membres. Si chaque profil était considéré comme un site à part, ce qui est le cas du point de vue du contenu, on n’observerait pas d’augmentation de la concentration de trafic, ce qui serait cohérent avec la théorie de la longue traîne.

En d’autre mots, ce qui est concentré ce n’est pas le contenu lui-même mais sa valeur économique. MySpace, Facebook et de nombreux sites ont réalisé qu’ils peuvent distribuer les outils de production tout en conservant le droit de propriété sur les produits qui en résultent. Une des caractéristiques économiques fondamentales du Web 2.0 est que la production est distribuée entre de nombreuses personnes et que les récompenses économiques sont concentrées dans les mains de quelques uns. C’est un système de métayage, sauf que les métayers sont généralement heureux car leur intérêt réside dans l’auto-expression ou la socialisation et pas dans le gain d’argent, et que par ailleurs la valeur économique de chacune de leurs contributions individuelles est minuscule. C’est seulement en agrégeant ces contributions sur une échelle massive - l’échelle du web - que l’affaire devient rentable. Pour le dire autrement, les métayers s’épanouissent dans une économie de l’attention pendant que les propriétaires s’épanouissent dans une économie monétaire. De ce point de vue l’économie de l’attention n’opère pas séparément de l’économie monétaire ; il s’agit simplement d’un moyen pour celle-ci de créer des données à bas prix.

Il est frappant pour moi que cette dynamique, qui je pense n’avait jamais été observée jusqu’à présent, du moins à cette échelle, est le phénomène économique le plus intéressant et le plus troublant qu’internet ait produit.

© 2006 Nicholas Carr

Risques faibles et réactions disproportionnées

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

Le pire ennemi du code

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



Comprendre les ingénieurs : faisabilité

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’.