« Tu seras un prêtre mon filsJe hais les touristes »

Un café, l'addition

07.08.10 | par Le Grincheux | Catégories: Mauvaise humeur, Mauvais esprit, Je hais l'informatique, Vieux con, Matheux pervers

Lorsque j'ai commencé à travailler avec des outils informatiques, j'avais à ma disposition un panneau de clefs, une perforatrice en code 29 et un télétype de Digital. À chaque erreur dans un programme, il n'y avait aucune façon simple de la corriger. Si ce n'était pas trop compliqué à faire, j'avais à ma disposition un rouleau de scotch opaque et une pince à tiercé, mais dans la plupart des cas, il fallait repasser par l'étape performation des cartes. Autant vous dire qu'à l'époque, on faisait attention à ce qu'on écrivait car entre l'édition, la compilation et l'exécution d'un programme, il pouvait se passer plusieurs heures et il fallait recommencer tout le cycle à chaque correction.

Fig. 1 : authentique carte perforée à 80 colonnes en code IBM à 12 lignes

J'ai utilisé des cartes perforées à quatre-vingts colonnes jusqu'en 1997, ayant même écrit un pilote pour utiliser une perforatrice en code 29 depuis une SparcStation 20 tournant sous Solaris 2.5.1. Le simple fait de pouvoir utiliser un vrai éditeur (vi), un compilateur Fortran (gcc 2.7.2.1 et le g77 correspondant) et un debugger (gdb/ddd) avant de perforer les cartes a été un progrès indéniable. Il ne restait plus que le coup de marqueur à mettre en biais sur la tranche de la pile de cartes. Pour ceux qui n'ont jamais travaillé avec des cartes, ce trait de marqueur permet de trier assez rapidement un monceau de cartes lorsqu'on s'est pris les pieds dans un câble et que l'ensemble d'un classeur de carte gît en vrac sur le sol de la salle machine. Pour être sûr que le périphérique de sortie donnerait un résultat lisible, j'avais même poussé le vice à écrire un pilote pour un télétype DecWriter II.

Fig. 2 : authentique télétype DecWriter II

L'apparition des éditeurs modernes (LSE ou EVE sous VMS/OpenVMS, vi sous Unix), la multiplication des langages de programmation et l'augmentation de la puissance des machines ont profondément transformé le rapport qu'un développeur peut avoir avec ses programmes en réduisant le temps nécessaire à l'édition.

Dans les années 80, je voyais essentiellement des programmes écrits en Cobol ou Fortran 66 ou 77 sur des cartes ou des rubans, ou à l'aide d'éditeurs orientés lignes qui n'étaient guère plus pratiques que les perforatrices. Je pense en particulier à l'éditeur EDIT.CMD de Flex9/UniFLEX. Ceux d'entre vous qui ont eu l'immense joie d'écrire du code Fortran pour Flex9 comprendront aisément ce que je veux dire. Les premiers micro-ordinateurs proposaient des éditeurs Basic un peu moins rébarbatifs mais pas beaucoup plus pratiques.

La mode du C apparaît au début des années 90. Avant cette époque, la puissance limitée des machines rendait obligatoire l'utilisation d'un langage adapté au problème à coder, essentiellement parce qu'il fallait que le programme soit compact donc que la majorité des opérations effectuées soient disponibles dans des fonctions intrinsèques au langage employé. Il était illusoire de surcharger la mémoire par des bibliothèques inutiles sous peine d'obtenir un laconique « out of memory error ». La plupart des développeurs ont néanmoins adhéré à cette mode du C en partant du principe que ce langage était capable de résoudre tous leurs problèmes. C'est une grave erreur. Le C a été écrit pour développer des systèmes d'exploitation et non pour un usage générique. Il est ainsi très difficile d'écrire un code propre en C et le C de référence à l'époque, le Kernighan et Ritchie, n'était absolument pas adapté aux calculs complexes. Lorsqu'on rajoute que le C est directement issu du slogan « il est interdit d'interdire », on se demande même pourquoi des non spécialistes ont utilisé ce langage pour autre chose que de la programmation système.

Par la suite, les utilisateurs ont pris conscience des limites du C K&R et ont spécifié un C ANSI subtilement différent du C K&R (voir les joyeusetés concernant les passages de paramètres sous forme d'int qui attrapent tous les débutants et moins débutants), puis un C++, version objet d'un C jugé trop impératif.

Aujourd'hui, l'immense majorité des développeurs ne jure plus que par Java. Java va résoudre tous leurs problèmes. Grâce à Java, le développeur moderne deviendra riche, sera musclé et sa femme va revenir. Euh, non, ça, c'est pour le marabout qui laisse des papiers à la sortie du métro, mais l'idée est en gros la même.

Je ne veux pas parler de la syntaxe du langage même s'il est évident qu'il y aurait beaucoup à dire. Personnellement, j'ai toujours préféré un langage impératif ou fonctionnel à un langage objet parce l'abstraction de la programmation objet est tellement grande qu'on ne sait plus exactement ce qu'on fait. Écrire un algorithme dans un langage objet est relativement facile. Pire, c'est à la portée de n'importe qui. En revanche, l'optimiser est beaucoup plus ardu. La conséquence immédiate est une débauche de ressources, tant du point de vue de l'occupation de la mémoire que de celle du processeur.

Je ne veux pas parler non plus de la machine virtuelle Java qui me semble être une aberration technique sans nom. Je n'arriverai jamais à comprendre pourquoi on compile un programme Java dans un format binaire intermédiaire pour l'exécuter dans une machine virtuelle. On me dira que c'est pour des raisons de portabilité, mais l'argument ne tient pas puisqu'il faut porter la machine virtuelle, ce qui n'est pas plus simple. Autant porter directement un compilateur s'appuyant sur des API fixes comme POSIX ou utiliser une bibliothèque d'abstraction. On sait faire cela depuis longtemps sans aucun problème. Ceux qui ne me croient pas peuvent regarder l'antique bibliothèque porting library et en particulier les jackets des anciennes version de VMS qui permettaient d'utiliser un code POSIX sur un système qui ne l'était pas encore.

Dans un premier temps, je trouve que Java, contrairement à ce qui est trop souvent dit, n'est pas un langage discriminant. En d'autres termes, il ne permet pas de séparer un bon programmeur d'un mauvais. Trop de choses sont à la discrétion de la machine virtuelle qui ne s'en prive pas comme la gestion de la mémoire et les différentes ressources du calculateur, et la conséquence immédiate est que n'importe quel développeur du dimanche peut écrire des applications complexes, souvent jetables parce que leurs codes sources ne sont pas réutilisables, sans comprendre exactement ce que son ordinateur fera. Il est très facile d'écrire un programme de quelques lignes demandant plusieurs centaines de mégaoctets pour effectuer une tâche basique et tout le monde est content.

Java ne parle jamais de pointeur ni de récursion. C'est trop complexe et il faut masquer ces deux notions importantes au programmeur. Pire, le programmeur ne doit même pas savoir que cela existe. On ne peut pas prétendre écrire un bout de programme sérieux en C sans parler de pointeur ; en Java, si. Or les pointeurs sont partout, même s'ils sont plus ou moins masqués dans des objets Java comme des listes chaînées, des tables de hashage et j'en passe.

Les heureux développeurs qui ont fait leurs armes dans les écoles suivant la mode Java n'ont jamais eu à se dépêtrer dans des fichiers core de plusieurs megaoctets, avec la seule aide d'une calculette hexadécimale, lorsqu'il s'agit de déboguer des algorithmes efficaces de gestion de la mémoire (tables de hashage, allocateurs, ramasse-miettes…) qui se terminent par un laconique message de violation d'accès. Pire, ils ne savent pas utiliser un debugger et mettent au point leurs programmes à grands coups de System.out.println(). C'est tellement pratique… De la même manière, ils n'ont jamais été confrontés à la programmation multithreadée et aux problèmes de concurrences même si le langage Java permet de définir des threads.

Je veux bien admettre que la programmation à l'aide de pointeurs ne soit pas nécessaire dans les trois quarts des programmes écrits aujourd'hui. Pire, je suis conscient que les pointeurs sont dangereux si on les laisse dans les mains de développeurs qui n'ont pas les idées claires et que la programmation fonctionnelle n'est que très peu utilisée en pratique.

Mais il reste le dernier quart, certainement le plus intéressant. Sans connaître ni maîtriser les pointeurs, il est illusoire de travailler sur un programme efficace ou un noyau de système d'exploitation. Il ne faut même pas espérer en comprendre le fonctionnement.

Sans comprendre la programmation fonctionnelle ou multithreadée, il est impossible d'écrire des algorithmes à la fois massivement parallèles et efficaces. Certes, Java dans certains cas arrive à utiliser des threads, mais ils restent dans une machine virtuelle. Ce n'est pas exactement une parallélisation de calculs.

Vous allez me dire que ce n'est valable que pour un quart des programmes. Certainement, mais ce n'est pas négligeable pour autant. Personnellement, en réécrivant la routine A* de la bibliothèque bien connue BOOST en C et Fortran, j'ai divisé par vingt le temps d'exécution de cette routine et divisé par dix la mémoire nécessaire à son exécution. Et BOOST n'est écrit qu'en C++, même pas en Java. Je n'ose imaginer ce qu'il en aurait été.

Rien n'est fait dans les formations Java pour apprendre aux étudiants à penser autrement que dans le paradigme Java. Ils n'arrivent pas à implanter un simple tri de liste chaînée. En revanche, ils sont capables d'assembler des tas de boîtes noires qui font la même chose mais dans une débauche de ressources tout à fait remarquable et qui ferait pleurer n'importe qui ayant travaillé sur des machines dont la mémoire vive était limitée à quelques malheureux kilooctets.

J'ai beaucoup de mal à imaginer que de tels développeurs deviennent un jour de véritables programmeurs. On me rétorquera que les écoles n'enseignent que ce que l'industrie demande, donc Java. Certainement, mais il ne faut pas oublier qu'il faudra toujours des artistes sachant utiliser des pointeurs et connaissant la programmation fonctionnelle ou la récursivité pour que ces développeurs aux petits pieds puissent coder leurs applications jetables. Il faudra toujours des gens capables d'écrire des systèmes d'exploitation ou des machines virtuelles, et ces développeurs Java en seront incapables.

Pire, ces formations orientées vers la programmation objet prétendent toutes simplifier la programmation par l'abstraction des différentes opérations dans des méthodes, des objets, des trucs et des bidules. Mais est-ce plus facile de réécrire une n-ième fois un arbre de hiérarchie d'objets ou d'utiliser une programmation fonctionnelle ? Personnellement, je ne suis pas sûr que la programmation objet soit aussi efficace qu'on le prétend dès qu'on parle de projets importants et complexes. Reprendre la définition d'objets lorsqu'ils sont manifestement inadaptés est quasiment impossible. Il vaut mieux jeter le code et le réécrire totalement.

Bref, je suis de plus en plus enclin à penser que la programmation objet n'a qu'un seul but : fournir des tas de programmeurs. Comme ces programmeurs seraient médiocres s'il fallait leur inculquer des concepts comme la programmation fonctionnelle ou les pointeurs, on préfère cacher leur médiocrité crasse dans la programmation objet où il est beaucoup plus difficile d'être mauvais. On privilégie la quantité à la qualité en changeant le paradigme et en comptant sur le fait que dans la plupart des cas, ça devrait passer. Effectivement, dans la plupart des cas, ça passe. Sauf de temps en temps où l'on fait un feu d'artifice à plusieurs millions de francs en faisant exploser une Fusée Ariane 5…

Vous me direz qu'en C, lorsqu'on a une erreur comme une violation d'accès, il est très souvent difficile d'en trouver la source. C'était vrai il y a quelques années. Aujourd'hui, il existe un nombre d'outils conséquent pour déverminer tous les accès fautifs à la mémoire, que ce soit en lecture ou en écriture, avant que le programme s'arrête sur une violation d'accès.

La conséquence de tout ça, c'est qu'un bon programmeur parlant C, Fortran, Ada, Scheme ou Haskell dans le texte arrivera à se mettre à Java en quelques jours et à écrire de bien meilleurs programmes qu'un développeur ayant cinq ans de pratique quotidienne de Java et ne connaissant que cela. La réciproque est fausse.

L'avenir n'est pas rose. Les hordes de développeurs Java écrivent actuellement du code non maintenable, ignoble, jetable, mais rapidement. La durée d'écriture d'une application est de plus en plus courte, ce qui nuit à sa qualité, mais cela ne semble encore gêner personne. Lorsque tous les dinosaures avec des écailles — ndlr. le dinosaure avec des écailles est l'ancêtre du geek — auront disparu, il ne restera plus que cette génération de sagouins qui n'aura plus les compétences requises à l'écriture de programmes efficaces.

À cet instant, on peut faire un parallèle avec la NASA. La NASA veut aujourd'hui envoyer à nouveau des hommes sur la lune et elle a annoncé qu'il lui faudra un certain nombre d'années pour y arriver. Je ne sais pas si vous avez déjà réfléchi au fait que l'ayant fait plusieurs fois entre 1969 et 1974, elle devrait pouvoir atteindre son but très facilement. Il y a juste un problème : toutes les compétences qui avaient permis à envoyer un homme sur la lune avec la puissance de calcul d'une calculatrice de poche actuelle ont disparu et il faut réinventer la roue.

La même situation risque de se produire à moyen terme dans le domaine de l'informatique. Après le café, il faudra régler l'addition et cette addition risque d'être salée.

 

3 commentaires

Evaluations des utilisateurs
5 étoile:
 
(1)
4 étoile:
 
(0)
3 étoile:
 
(0)
2 étoile:
 
(0)
1 étoile:
 
(0)
1 note
Evaluation moyenne des utilisateurs:
*****(5.0)
Commentaire de: Jean-Christophe
*****

Je viens de lire “Un café, l’addition” qui m’a réchauffe le coeur bien mieux qu’un café, car je méditais ce même genre de pensées depuis quelque temps (en me faisant copieusement insulter si j’avais l’inconscience de tenter de les partager). Cette lecture m’a révélé que “je ne suis pas seul” !

Vos considérations sur Java et le langage objet, sur cette nouvelle race de programmeurs, sur les conséquences futures qui couvent sous la cendre sont presque transposables telles quelles au domaine de l’électronique. Avec un micro-contrôleur et quelques bouts de code piochés sur internet ici et là, n’importe qui peut se bricoler un truc qui “marchotte” sans savoir programmer ni comprendre le fonctionnement d’un circuit électronique, et en étant encore moins capable d’en calculer quoi que ce soit. Certes les bricoleurs ont droit à leur domaine, mais il serait bon qu’ils s’y cantonnent.

Or, dans le domaine professionnel arrivent depuis quelques années un nouveau genre de “spécialistes” fournis par les écoles pour les besoins de l’industrie. L’électronicien (niveau BTS) a du mal à lire un schéma, est souvent incapable d’utiliser les outils mathématiques (tels que l’intégration ou la dérivation) tout simplement parce que ce n’est plus ce que l’on attend de lui. Un circuit électronique numérique peut être conçu par quelqu’un qui n’en a aucune maîtrise, ni même les bases, grâce à un jeu (sic) de logiciels faits justement pour ça.

Que ce même électronicien comprenne comment fonctionne le circuit, c’est une autre question qui n’intéresse personne. Au point qu’aujourd’hui, les concepteurs en électronique analogique se font rares : or le numérique peut être vu comme une application particulière de l’analogique (je vais me faire incendier pour avoir dit cela).

Les techniques et la technologie sont plus pointues, et en même temps les techniciens sont moins performants : il ne faudra pas s’étonner quand les machines caleront et que les avions tomberont du ciel dans votre jardin.

Oublions tout ceci avec un peu de lecture : http://powerdown.free.fr/rp.html#FR

À bientot sur UseNet, cher Grincheux.
(tant qu’internet fonctionne encore)
Jean-Christophe

10.08.10 @ 14:53
Commentaire de: Le Grincheux

Pourquoi vous faire incendier ? J’ai été enseignant en électronique analogique et numérique, option électronique amusante à tubes et composants discrets. C’est exactement ce que je disais à mes étudiants (école d’ingénieurs ayant pignon sur rue) : on ne peut faire de l’électronique numérique sans comprendre l’analogique. Prétendre le contraire est une ineptie. Ce qui est grave n’est pas que le circuit ne fonctionne pas, mais qu’il fonctionne à peu près sans que son concepteur n’en comprenne le fonctionnement. Avec la dispersion des composants, il pourra se passer des choses amusantes ou tragiques.

10.08.10 @ 15:07
Commentaire de: Jean-Christophe

Me faire incendier non par vous, mais par une majorité de mes interlocuteurs. Certains sont enseignants, et supportent difficilement qu’on leur fasse remarquer une baisse constante et inquiétante du niveau des élèves (et pas seulement en électronique, loin de là).

Et je distingue “école” et “grande école". Je n’en citerai aucune, mais j’ai bossé avec un jeune ingénieur électronicien qui en savait bien moins qu’un ancien nanti du BAC. Quand ce qu’il faisait ne fonctionnait pas, il ne savait pas pourquoi, et quand ça fonctionnait il ne savait toujours pas pourquoi mais s’empressait de boucler le tout avec un papier cadeau. Par la suite il a dû débugger son soft ficelé à partir de bouts de code C récupérés de-ci de-là, auxquels il ne comprenait rien.

En ce qui concerne l’électronique, les notes d’application des “data sheets” des composants lui évitaient de faire réellement de la conception, ce qui nous ramène au cas de la programmation par détournement de routines écrites par d’autres. Quant à la réparation de l’électronique, sa technique consistait simplement à jeter les cartes.

Un jour nous discutions autour d’un schéma de carte d’entrées/sorties et j’ai réalisé qu’il ne comprenait rien dès qu’il y avait des transistors. Il soutenait que plus personne n’utilisait ces sales bestioles. Je lui ai demandé ce qu’il y a dans les circuits intégrés, et comment il construirait un ampli audio de puissance : je vous laisse deviner sa réponse.

Ce que je considère comme étant le problème de base est ce manque total de désir de comprendre qui semble être la norme (sauf rares exceptions). Même un simple schéma basé sur des AOPs leur est incompréhensible, dès que ces AOPs sont câblés autrement que les circuits standards appris à l’école (filtres, comparateurs, etc). Même remarque à propos de circuits à portes logiques, registres à décalage, etc.

La conception se résout alors à répéter mécaniquement ce qui a été appris sans jamais avoir été bien compris. J’ai vécu maints exemples en électronique et programmation, mais je m’arrête là. Désolé de m’être laissé emporter, mais il y a de quoi s’inquiéter.

10.08.10 @ 16:28


Formulaire en cours de chargement...