Hérésie (part one)

L'archétype du programmeur est l'individu qui va tous las matins à son bureau dans une grosse compagnie et développe en langage de haut niveau des choses pas toujours drôles mais qui appartiennent au domaine du possible. Dave Small, lui, a créé sa boîte, vit de l'émulation Mac sur Atari pourtant jugée "impossible" par des spécialistes, et code en assembleur. C'est en ce sens un anti-conformiste. C'est pourquoi il est bien placé pour vous proposer ce mois-ci une petite étude caustique du milieu des développeurs qui se voulant tous exactement aussi anti-conformistes que les autres.


Non-conformistes?


De prime abord, beaucoup de programmeurs semblent s’afficher comme des non conformistes absolus. Le plus gros choc survient en général lors de la première recontre. Imaginez un type portant une queue de cheval lui descendant jusqu’aux fesses, maintenue par un élastique et une généreuse couche de sébum, ainsi qu’une barbe à faire pâlir d’envie Fidel Castro. En outre, l’individu fait de l’exercice chaque jour, et prend une douche… euh… tous les mois? Ce qui fait que, tandis que vous lui serrez la main, vous vous placez habilement contre le vent et vous vous demandez où vous pourriez trouver un désinfectant au plus vite. Car cette poignée de main évoque les léchouilles gluantes d’un chien errant sortant de quelque poubelle.
J’ai rencontré tant de gens comme celui-là que je ne les trouve même plus exceptionnels. Si vous vouIez vivre cette expérience exaltante, allez au centre informatique de l’université la plus proche, et cherchez des étudiants de troisième cycle. Mais cette impression de non-conformisme ferait place à la stupéfaction si vous voyiez une cinquantaine de ces bidouilleurs ensemble. Ils ont l’air de clones. Ils sont en fait tous absolument conformes à un certain code! ll est hilarant de voir qu’ils ressemblent en cela à ces adolescents « non- conformistes » qui portent les mêmes jeans, les mêmes coiffures punk, et conduisent des voitures de sport. [NdT : on trouve aux USA des voitures de sport d’occasion à moins de 2000 doIlars, le permis est à 16 ans, iI n,y a pas de vignette, et l’essence 4 est fois moins chère qu’en France. C,est pourquoi même un ado désargenté peut s’offrir une telle voiture au prix d’un boulot d’été.].
Par ailleurs, ces bidouilleurs ont en commun beaucoup d’opinions sur la programmation et ne sauraient mettre en doute ces croyances. Osez le faire, et, croyez-moi, vous vous ferez expulser de la clique avant de comprendre ce qui arrive. Je le sais, j’ai émis un doute. Je ne peux m’en empêcher, ça fait partie de mon type de personnalité. D’ailleurs, j’ai passé jadis un test mesurant le degré de conformisme, et mon score était presque nul. C’est pourquoi leur attitude me donne des boutons, en particulier à raison d’une douche par mois.

Pour votre édification, je me livre donc ici à quelques propos hérétiques, et m’attends d’ailleurs à recevoir des tomates la prochaine fois que je me présenterai à un salon informatique. Sans compter les tomates « virtuelles » lancées via les réseaux Internet et USENET (voir mes coordonnées à la fin de l’article). Faites attention, mon sélecteur de tir, qui est d’habitude en position « coup-par-coup de précision », est pour cet article placé sur  » rafales continues ». Comme vous le savez sans doute, l’arme se relève en tir automatique, et tout servant de mitrailleuse vous dira qu’il faut ajuster le tir, c’est-à-dire observer les impacts et corriger. C’est pourquoi, si certains de mes arguments trop généraux vous semblent àcôté de la plaque, essayez de voir quel but je vise maladroitement, quels principes j’essaie d’exprimer, avant d’ouvrir le feu en représailles!


Niklaus Wirth n'est pas un dieu


Le bon professeur Wirth est l’inventeur du Pascal et de Modula. C’est lui qui a mis le monde entier sur les rails de la programmation structurée. Le Pascal est uniquement un langage d’enseignement de la programmation, qui était censé montrer comment la programmation struturée marchait. ll n’a jamais été conçu pour un usage dans le monde réel, ce qui est par contre le but de Modula (c’est Wirth lui-même qui le dit). Franchement, si j’étais lui, je ne serais pas sûr de vouloir passer à la postérité pour le Pascal. Mais malheureusement, tout ce que dit Wirth est noté aussi scrupuleusement que si c’était tiré des Tables de la Loi, tout comme le moindre mot de Brian Kernighan ou Dennis Ritchie est pris comme référence pour le langage C. Ce qui est aussi aburde que si on on suivait les préceptes d’Henry Ford pour construire une Ford modèle 1992 sous prétexte qu’il a inventé Ie Modèle T. Il y a des gens qui ne deviennent jamais adulte : quand ils étaient petits, leurs héros étaient Musclor et Superman; maintenant, c’est en Wirth, ou Kernighan et Ritchie, qu’ils ont la foi absolue. Cette vénération irréfléchie est toujours malsaine. Je ne sais plus qui a dit que le mot « croire » est le plus effrayant, car il implique que le cerveau est déconnecté.
Ainsi, bien que Wirth ait inventé le Pascal pour l’enseignement, ce langage a été implémenté sur de nombreux ordinateurs. Et dans le monde réel, des programmeurs se sont rapidement rendu compte de ses défauts. En particulier, ce langage est restrictif. Vous aviez beau savoir ce que vous vouliez faire, ce stupide langage ne vous le permettait pas. (Les puristes vous diront que ce que vous vouliez était donc mauvais. Billevesées! Vous avez payé votre machine, vous pouvez en exiger ce que vous voulez.) Le Pascal est presque dépourvu d’entrées\ sorties, et se limite à lire ou écrire un caractère ou une ligne à la fois dans un fichier. Très impressionnant, hein? Ce n’est pas moi qui irait écrire des programmes dans un langage qui vous lie une main dans le dos.
Je pense que j’ai une profonde haine du Pascal pour deux raisons. Primo, on a essayé de m’en gaver de force au lycée, d’où je me suis échappé juste avant qu’ il ne devienne obligatoire (et rende à mon avis les ordinateurs incompréhensibles à la majorité des gens auxquels la notion de structure est étrangère). Et secondo les ROM du Macintosh, sur lesquelles j’ai passé tant de temps, sont principalement écrites en Pascal, ce qui m’a obligé à avaler les horreurs produites par le compilateur qui a engendré le code assembleur stocké dans ces ROM.
Il y a aussi dans ces ROM de l’assembleur fait-main par Andy Hertzfeld, un magicien, et il est très instructif de comparer ce code propre et rapide avec l’abominable saleté pondue par le Pascal (toutes ces instructions LlNK inutiles, par exemple). Le code machine engendré par cet abruti de compilateur est horriblement inefficace. Moi, quand j’écris un programme, j’aime pouvoir être fier de sa rapidité et en tirer quelque gloire.
C’est peut-être pour cela que les programmeurs chez Apple ne mettent plus leurs nom dans leurs programmes. Peut-être est-ce ausi pour cela que beaucoup d’entre eux viennent juste d’être licenciés? Non, je suis sûr qu’ils écrivaient du beau code. C’est plutôt dans la haute hiérarchie que cela n’allait pas.
Avis aux puristes : je suis conscient des différences entre le code machine binaire et l’assembleur qui est sa forme symbolique. Pour cette article, j’ignore cette différence. Rasseyez- vous, ça continue.


La programmation structurée est une antiquité


Les bidouilleurs utilisent la programmation structurée, ça fait partie de leur conformisme. Eh bien, moi pas, et mes tentatives pour l’utiliser se sont soldées par des échecs cuisants. Il me semble qu’écrire un programme de cette manière revient à me faire violence. La programmation structurée reflête un certain type de personnalité, le type NT selon le profil de Myers-Briggs, que j’ai découvert être celui de pratiquement tous les programmeurs. j’ai écrit un article à ce sujet [NdT : voir ST-Mag n° 64]; brièvement, je rappelle que presque tous les bidouilleurs ont une personnalité d’un type rare, présent chez seulement une personne sur dix, et ont des raisonnements et des réactions très différentes de ceux de la majorité. Des psychologues l’ont également remarqué. Les NT sont fondamentalement des architectes, et tout dans un programme informatique reflête cette mentalité. Je ne suis pas un NT, je me situe même à l’opposé dans les tests. C’est pourquoi je comprend l’étonnement de la majorité des gens devant l’informatique. Les partisans de la programmation structurée croient que tous les problèmes de programmation peuvent être scindés en quelques constructions de base : la boucle DO-WHILE, l’instruction CASE (qui équivaut à une série de lF-THEN-ELSE), et quelques autres. Et ils croient aussi que c’est ce qui doit être fait dans tous les cas. Pour un bidouilleur NT, c’est tout-à-fait évident et intuitif. Pour les 90% du reste de la population, c’est ahurissant. lmaginez un enfant avec une boîte Lego, séparant et réassemblant ses pièces, et vous avez un futur NT qui fera de la programmation structurée.


Il faut utiliser des sous-programmes


Pour s’accommoder de la complexité de certains programmes, les adeptes de la programmation structurée recommandent de scinder un programme en 36 000 petits sous- programmes, dont chacun ne fait qu’une seule chose. Pour moi, cela rend le tout encore moins compréhensible qu’un seul gros programme. C’est comme écrire un roman dont chaque paragraphe est mis dans un fichier séparé! (Ou comme faire un magazine à partir d’articles contenus dans des fichiers différents… Pauvre rédacteur-en chef!).
Adoptez par exemple le style de programmation de chez AT&T, où chaque sous-programme doit se trouver dans un fichier séparé, et vous vous retrouvez aux prises avec un bourbier innommable. Vous avez alors besoin du programme MAKE auquel vous devez préciser, dans un fichier de commande, dans quel ordre s’emboîtent ces morceaux pour construire votre programme. Dans ce genre de situation, il faut tout arrêter et vérifier que la belle idée colle toujours à la réalité (ce que j’appelle une vérification de réalité). Donc, le programme a été scindé à grand-peine en 500 modules, avec force variables importées et exportées, et, toujours à grand-peine, un fichier de commande pour MAKE a été écrit pour réassembler tous ces morceaux. Question : qu’y a-t-il dlanormal dans cette situation? Formulez votre réponse en utilisant les mots  » heures » et « jours ».
Contre-exemple : comparez avec Dave le simplet. Moi, j’écris le programme en un seul morceau, je le compile, et c’est fini. Je m’ épargne l’effort considérable de le scinder et le non moins considérable travail de réassemblage.


Les ordinateur ne sont pas parfaits


Ajoutez à cela la 17ème Loi de l’Informatique de Small, « Les ordinateurs ne sont pas encore parfaits ». Les outils de scindage et de réassemblage des morceaux ne le sont pas non plus.

Pendant que vous compilerez séparément vos différents fichiers avant de les passer tous ensemble à l’éditeur de liens, vous mettrez votre machine à rude épreuve. Et vous découvrirez, à la manière forte, chacun des bogues de votre système d’exploitation, de votre compilateur et de votre éditeur de liens. J’en ai vu tellement que je ne soupire même plus de dégoût. J’apprécie vraiment lorsque ALN (le nouvel éditeur de lien d’Atari) me donne un message d’erreur en traitant des fichiers qui passaient sans erreur sur le vieux LO68/RELMOD, par exemple (devinez un peu lequel j’utilise). Franchement, si quelque chose n’ allait pas, je l’aurait découvert avant; j’ai recompilé ce code des milliards de fois. Et je pourrais citer bien d’autres exemples.
Ne faites pas l’erreur de croire que les ordinateurs sont parfaits. Un tantinet de saine paranoïa s’impose. Si vous comtemplez l’historique de n’importe quel ordinateur vous verrez immanquablement le même scénario : l’ordinateur sort, et les corrections de bogues suivent. Prenons Atari. Citons en vrac Ie bogue des 40 dossiers, celui du caractère « souIigné » dans le sélecteur d’objet, les 97 bogues d’AS68 dont j’ai la liste, le bogue exaspérant de RELMOD qui lui fait remplir tout le disque si le fichier en entrée est incorrect, les choix discutables de conception du matériel (amener le signal RESET jusqu’aux lecteurs de disquette sans amplifioation? Non, mais je rêve!), et j’en passe.
Alors, savez-vous ce que je fais? Je m’en tiens à un seul assembleur et éditeur de liens, et quand je leur trouve un bogue, je l’ajoute au dossier BOGUES de ma machine. Je ne change d’ outil que dans les cas désespérés, parce que je sais pouvoir m’affranchir des bogues d’un outil donné. (Ne pas mettre deux labels à la suite sans instruction dans AS68, par exemple. Ne pas utiliser la compilation conditionnelle avec AS68.) C’est en tremblant de frousse que je suis passé à l’assembleur HiSoft, je reconnais que, mis à part quelques anomalies (comment diable le fait-on produire du code relatif au PC?), il marche bien.
Encore une petite vérification de réalité. Figurez-vous que mon émulateur Mac, le Spectre GCR, est obligé de corriger des défaillances de programmes Mac lorsqu’ ils essaient d’écrire à l’adresse zéro à cause d’erreurs de logique ou de programmation. Pour mémoire, je dirais seulement que la moitié des programmes Mac, y compris la plupart de ceux, très connus, qui ont fait le succès de la machine, sont truffés d’erreurs d’écriture à l’adresse zéro. Ce sont des programmes écrits principalement en C et en Pascal, tournant sous un système d’ exploitation écrit en Pascal, et écrits par des gens qui sont considérés comme étant parmi les meilleurs de la profession. Eh bien, même eux finissent par ne plus pouvoir se souvenir de leurs pointeurs et de la validité de ceux-ci, tant sont subtiles certaines opérations de déplacement de mémoire.

Rien qu’à l’allumage du Mac, avant d’en arrlver au bureau, je compte au moins huit erreurs d’écriture en zéro! Et qui a écrit ça?La seule raison pour laquel le Mac s’en tire est qu’à l’adresse zéro se trouve, par le plus pur des hasards, de la RAM, ce qui évite donc une erreur de bus (sur le ST, au contraire, c’est de la ROM, c’est pourquoi il m’a fallu arranger cela!). Mais souvent, ces bogues reviennent hanter le programme; après tout, cette écriture en zéro était faite pour stocker une donnée, et quelque chose d’important n’a pas été stocké à sa place. Quand le programme le relit, les bonnes valeurs ne s’y trouve pas, et boum! Erreur d’adresse, le plus souvent (3 bombes sur le ST, ID=2 sur le Mac). Finalement, la méthode du ST est la meilleure et il serait bon sur le Mac de modifier l’adresse zéro pour que toute écriture y engendre une erreur, afin que les programmeurs corrigent leurs codes. Apple, rendons-lui cette justice, encourage cela.
Si vous acceptez de signer un accord de non-divulgation, je veux bien vous faire faire un petit tour à vous soulever le coeur à travers la galerie des programmes Mac qui ne tournent que par accident. Je ne veux pas les nommer ici parce que j’ai horreur des procès.

Loi de Small n° 1 5 : les vrais programmeurs s’abonnent à tous les magazines et se connectent à tous les réseaux qu’ils peuvent atteindre, et découpent ou sauvent dans des fichiers les mentions de bogues et les astuces de programmation. Vous seriez surpris de voir combien un seul petit article peut vous aider.


En assembleur, on voit ce que fait la machine


J’aime tirer une leçon de mes erreurs. Je trouve que lorsque je me tiens en retrait de ce que fait mon code dans la machine, comme par l’intermédiaire du langage C, ce code devient beaucoup plus dur à déboguer. Or, le débogage est un gros pourcentage du temps du programmeur! En utilisant l’assembleur, je peux tracer, pas à pas, mes instructions, et trouver l’erreur.
En C? Laissez tomber. ll faut revenir au débogage de l’âge des cavernes en mettant dans le code des lignes affichant « J’ai exécuté la line 10! », « J’ai exécuté la line 20! » et autres atrocités. Je ne voudrais pas passer ma carrière à lire et relire mon code C à la recherche d’un bug que je ne peux pas tracer directement. Vous savez, ces fameux problèmes à se gratter la tête de perplexité. Et le pire, c’est qu’il s’agit parfois d’un problème dans le compilateur, ses bibliothèques ou le système d’exploitation, pas d’une erreur de votre part, et vous ne le trouverez jamais. Point final.

En assembleur, vous le trouverez en traçant votre code, parce que vous voyez l’ ordinateur à son niveau réel, et non à travers quelque fiction de machine parfaite. Vous pouvez même bidouiller des choses… disons, du code relatif au PC… que vous ne pouvez pas écrire directement dans votre source, en entrant des octets manuellement.

Du coup, j’ai acquis une accoutumance à l’assembleur. Quand mon programme plante, je trotte jusqu’aux adresses $380-$3FF et je regarde à quelle adresse précisément je me suis planté. Ou bien je lance le débogueur en mode trace et je regarde le plantage se dérouler. Ou mieux, j’utilise l’émulateur en circuit Zax [NdT : les ICE (In-Circuit Emulators) sont des appareils qui reproduisent la circuiterie d’un microprocesseur comme le 68000, et donnent accès en temps réel aux états internes, aux registres et au moindre bit du microprocesseur émulé combien coute une boite de viagra.] Si votre programme plante, le Zax vous révélera les 4096 dernières instructions exécutées par votre machine. Une sacré loupe de Sherlock Holmes! Ce qui me permet de corriger le bogue immédiatement. Fini la perplexité. Le problème apparaît en général instantanément.

Si vous aimez le son du Spectre, sachez qu’il est là parce que le Zax m’a prouvé que la circuiterie de l’Atari accomplissait quelque chose réputé « impossible ». Qui pourtant est là. Le Zax a beaucoup amélioré le Spectre à partir de la version 3.0. (pour être honnête, les éditeurs de compilateurs C sortent maintenant des débogueurs symboliques qui permettent de tracer ce que fait le code C, et ces outils ont plus d’une ressemblance avec les traces assembleurs. Disons que comparé au débogage en assembleur et au Zax, ces outils abordent l’ aube de l’ère industrielle.)


Plus facile à maintenir


Les zélateurs de la programmation structurée affirment que l’on doit diviser un programme en utilisant seulement quelques structures simples. En procédant ainsi, affirment les conformistes, vous le rendez plus simple à maintenir.

Foutaises! Les problèmes les plus difficiles à résoudre en programmation sont les plus simples conceptuellement. Ces problèmes ne sont pas simplifiés par un quelconque style de programmation. (Les autres problèmes sont sans doute des fautes de frappe ou des bugs dans ce crétin de compilateur C. Exemple : « Est-ce le fabricant a sorti une mise à jour du compilateur qui ne force pas les définitions SHORT à être alignées aux mots ? Crénom, pas étonnant que ce code ait eu des problèmes!… »)

Tenez, considérez un pré carré entouré d’une clôture, dont les poteaux sont espacés de 4 m. Le pré fait 40 x 40 m. Combien de poteau y a-t-il sur chaque côté? Et au total? Déjà, contrairement à ce qu’on pourrait penser hâtivement, il n’y a pas 10 poteaux par côté, mais 11. En effet, il faut un poteau au coin pour marquer le début d’un côté, et ensuite on en compte 10, un par mètre. En programmation, cela correspond à une boucle qui débute à 0. Pour aller de 0 à 10 inclus, il y a 11 itérations. Cette erreur classique de programmation est si connue qu’elle a justement été baptisée « erreur du poteau » . Pour moi, cela représente parfaitement le problème phiiosophique extrême de faire correspondre au monde réel ce que dit l’ordinateur. ll y a beaucoup d’ erreurs classiques de ce genre. Et diviser le problèmes en structures ne peut vous aider à les résoudre, car ces problèmes ont leur origine dans votre tête, pas dans la machine!
Ah oui, et le nombre total de poteau? Méditez cet exemple parfait de bonne réponse bâtie sur un mauvais raisonnement, comme ces programmes qui marchent par hasard : « 40 poteaux au total, bien sûr, puisqu’il y en a 10 par côté. »


L'erreur du roi Salomon


Je voudrais mentionner une erreur classique de méthode de programmation que j’ appellerais « l’erreur du roi Salomon ». Vous vous souvenez de l’histoire biblique du roi Salomon qui proposa de couper un bébé en deux pour résoudre une dispute entre deux femmes s’en prétendant mère? Eh bien, découpez un programmes en morceaux, et vous aussi découvrirez qu’il est pénible de chercher les interactions entre les différents modules, simplement parce que vous ne pouvez pas les voir à l’écran en même temps. Je suis d’autant plus sensibilisé à ce problème que j’écris. Quand je rédige un article, j’aime en voir le maximum à l’ écran.
Quand je le peux, j’utilise un écran Moniterm, et j’offre une forte récompense à quiconque modifiera un traitement de texte pour qu’il puisse utiliser les deux « pages » d’un Moniterm [NdT : Dave Small ignorait alors que des traitements de texte européens ont cette possibilité]. En voir beaucoup aide à rendre l’article cohérent. Non? Alors allez écrire sur un écran de huit lignes et relisez la bouillie informe qui en émergera. Quand je veux maintenir quelque chose, je charge le code source entier dans un éditeur. J’ai parsemé le code source de commentaires contenant des mots-clés qui me servent de repères. Si je veux, disons, modifier le code qui gère la souris dans Spectre, je fais une recherche du mot-clé « trouve-souris », lequel se trouve dans un commentaire en tête du segment de code en question. Je peux alors regarder ce bout de code et ses interactions avec le reste sans avoir à ouvrir des fenêtres, charger d’autres fichiers, etc. Je ne saurais vous dire combien d’erreurs d’ interaction j’aurais manqué si tout n’avait pas été lisible en un seul endroit.


A Suivre


J'arrête mes hérésies pour ce mois-ci. Le mois prochain, je jetterai un oeil à l' hérésie en C et en Basic.
A la prochaine fois!

Traduction et adaptation : Password

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *