L'Histoire de Mel, un Vrai Programmeur

par Éric Marsden

Présentation du Jargon File

Le Jargon File (connu également sous le nom de Hacker's Dictionnary) est un recueil du vocabulaire caractéristique de l'espèce d'individu appelé en anglais hacker. Il contient également quelques histoires qui font partie de la sous-culture des hackers, dont celle que je vous présente ici, qui célèbre un programmeur pur et dur d'une autre époque, un dénommé Mel. C'est en fait la traduction d'un article qui a été posté sur le Usenet par Ed Nather le 21 Mai 1983.

L'histoire de Mel, un Vrai Programmeur

Un récent article dévoué au cote macho de la programmation contenait le propos suivant:

Les Vrais Programmeurs programment en FORTRAN.

Voici la réponse de Ed Nather:

Peut-être est-ce le cas aujourd'hui,
dans cette ère décadent de bière légère,
de calculettes de poche et de logiciels conviviaux
mais dans le bon vieux temps,
à l'époque ou le terme "logiciel" sonnait faux
et les Vrais Ordinateurs étaient constitués de
tambours magnétiques et de tubes à vide,
les Vrais Programmeurs programmaient en code machine.
Pas en FORTRAN. Pas en RATFOR. Pas même en assembleur.
En code machine.
De l'hexa à l'état brut, sans floritures, inscrutable.
Directement.

Afin d'éviter qu'une nouvelle génération entière de programmeurs
grandissent en ignorant ce passé splendide,
je me sens dans l'obligation de décrire,
du mieux que je peux malgré le décalage entre générations,
comment un Vrai Programmeur s'y prenait pour écrire du code.
Je vais l'appeler Mel,
car c'était son nom.

J'ai rencontré Mel pour la première fois lorsque je suis entré
à la Royal McBee Computer Corp.,
filiale depuis longtemps éteinte de ce fabriquant de machines à écrire.
La firme produisait alors le LGP-30,
un ordinateur petit et bon marché (pour l'époque)
doté d'une mémoire à base de tambours magnétiques,
et venait de commencer la fabrication
du RPC-4000, ordinateur plus puissant,
plus rapide, mais toujours muni d'une mémoire à tambour.
Les tores de ferrite coûtaient bien trop cher,
et de toute manière ils n'allaient pas durer.
(Voila pourquoi vous n'avez entendu parler ni de la compagnie,
ni de l'ordinateur.)

J'avais été embauché pour écrire un compilateur FORTRAN
pour cette nouvelle merveille et Mel était chargé
de me faire une visite guidée, m'en
faire découvrir les splendeurs intimes.
Mel n'approuvait pas des compilateurs.

``Si un programme ne peut pas réécrire son propre code'',
demandait-il, ``a quoi peut-il bien servir?''

Mel avait écrit
-- en hexadécimal --
le programme informatique le plus populaire que possédait la compagnie.
Il tournait sur le LGP-30
et jouait au blackjack avec les clients potentiels
dans les salons d'informatique.
Son effet fut toujours remarquable.
Le stand du LGP-30 était rempli à craquer à chaque expo,
et les vendeurs d'IBM restaient seuls
à discuter entre eux.
Ce programme faisait-il vendre des ordinateurs,
voila une question qu'on ne se posaint point.

La tâche de Mel était de réécrire
le programme de blackjack pour le RPC-4000.
(du code portable? Kesako?)
Le nouvel ordinateur employait un
mode d'adressage un-plus-un,
dans lequel chaque instruction machine --
en plus du code de l'opération
et de l'adresse de l'opérande --
comportait un deuxième adresse indiquant la position,
sur le tambour magnétique en rotation,
de la prochaine instruction à exécuter.

En termes modernes,
chaque instruction était suivie d'un goto!
Vas voir ce qu'en dis M. Pascal.

Mel adorait la RPC-4000
car elle lui donnait la possibilité d'optimiser son code:
c'est à dire, de disposer les instructions sur le tambour
de telle manière que lorsqu'une d'entre elles finissait son travail,
la prochaine serait en train d'arriver sous la ``tête de lecture''
et serait disponible pour être exécutée immédiatement.
Il y avait un programme qui faisait ce travail,
un ``assembleur optimisant'',
mais Mel refusait de s'en servir.

``Tu ne peux jamais savoir là où il va mettre les trucs'',
expliquait-il, ``donc il faudrait utiliser des constantes séparées''.

J'ai mis longtemps à comprendre cette remarque.
Comme Mel connaissait le code numérique
de chaque code d'instruction,
et qu'il fixait lui-même ses adresses sur le tambour,
chaque instruction qu'il écrivait pouvait également être
considérée comme une constante numérique.
De telle sorte qu'il pouvait profiter d'une précédente instruction add,
par exemple, pour en prendre le produit,
pour peu qu'elle eu la bonne valeur numérique.
Son code n'était pas facilement modifiable par
un autre programmeur.

J'avais comparé le programme optimisé ``main'' par Mel
avec le même code généré par l'assembleur optimisant,
et celui de Mel tournait systématiquement plus vite.
Ceci car la méthodologie « de haut en bas » de conception de
programmes informatiques n'avait pas encore vu le jour,
et que Mel ne s'en serait de toute manière jamais servi.
Il écrivait les parties intérieurs de ses boucles en premier,
afin qu'il puisse leur affecter
les adresses optimales sur le tambour.
L'assembleur optimisant, n'étant pas aussi intelligent que Mel,
ne pouvait faire pareil.

Mel n'écrivait pas non plus de boucles d'attente,
même lorsque notre stupide imprimante
exigeait pour fonctionner correctement un petit délai
entre les caractères en sortie.
Il positionnait tout simplement les instructions sur le tambour
de telle façon que chaque instruction se trouvait
juste derrière la tête de lecture
au moment ou elle allait servir.
Il inventa un terme inoubliable pour cette manière de procéder.
``Optimum'' est un terme absolu,
de la même manière que l'est ``unique'', mais il est devenu
pratique courante à l'oral de rendre ce mot relatif:
``pas tout à fait optimum'' ou ``moins optimum''
ou ``pas très optimum''.
Mel appelait le positionnement maximisant le temps de
recherche des instructions le positionnement le ``plus pessimiste''.

Une fois son programme de blackjack termine
(``Même la séquence d'initialisation est optimisée'',
disait-il avec fierté),
il reçu une Demande de Modification de la part du département Ventes.
Son programme utilisait un générateur de nombres aléatoires
élégant (et optimise)
pour mélanger et distribuer les ``cartes'',
et certains des vendeurs pensaient que
le système était trop équitable,
puisqu'il arrivait que des clients perdent.
Ils voulaient que Mel modifia le programme
de manière à ce qu'ils puissent,
en positionnant un bouton sur la console,
changer les probabilités pour faire gagner le client.

Mel s'est regimbé.
Il trouvait cette demande franchement malhonnête
(ce avec raison),
qu'elle trahissait son intégrité personnelle de programmeur
(ce encore avec raison),
et refusa donc d'effectuer la modification.
Le Chef des Ventes a parlé à Mel,
de même que le Grand Chef et, sous la pression de ce dernier,
certains collègues programmeurs.
Mel a fini par céder et a modifié son programme,
mais il s'est trompe dans le sens du test
et, lorsque le bouton était en position ``triche'',
le programme trichait, et gagnait à tous les coups.
Mel était ravi de son erreur,
prétendant que son subconscient avait un sens éthique incorruptible,
et refusa catégoriquement de changer son code.

Une fois que Mel eut quitté la compagnie pour des terre$ plus accueillantes,
le Grand Chef me demanda de jeter un coup d'oeil au code
pour voir si je ne pourrais pas trouver le maudit test,
histoire de l'inverser.
Sans enthousiasme, j'acquiesça.
Déchiffrer le code de Mel fut une véritable aventure.

J'ai souvent eu l'impression que la programmation
est une forme d'art
dont la vraie valeur ne peut être appréciée que
par un autre ésprit versé dans ce même art obscure;
de magnifiques bijoux et des coups brillants
restent, par la nature même de la programmation,
cachées de la vue et de l'admiration humaine,
parfois éternellement.
On peut apprendre beaucoup sur un individu
simplement en lisant son code,
même en hexadécimal.
Mel était, à mon avis, un génie non reconnu.

Le choc le plus rude me frappa
lorsque je trouvait une boucle innocente qui ne
comprenait aucun test. Aucun test de sortie.
Le raison simple exigeait qu'il devait s'agir d'une
boucle infinie, dans laquelle le programme tournerait
a l'infini, sans jamais s'arrêter.
À l'exécution du programme, cependant, la boucle
était franchie sans problème.
J'ai mis deux semaines à comprendre.

Le RPC-4000 jouissait d'une ressource très moderne
nommée registre d'indice.
Elle permettait au programmeur d'écrire une boucle
en utilisant une instruction indicée ;
à chaque tour de la boucle,
le nombre dans le registre d'indice
était ajouté à l'adresse de cette instruction,
de façon à ce qu'elle pointe
vers le prochain membre d'une série d'éléments.
Le programmeur n'avait qu'à incrémenter le registre d'indice
à chaque tour dans la boucle.
Mel ne s'en servait jamais.

Au lieu de cela, il plaçait l'instruction dans un
registre machine, ajoutait un à son adresse,
et la remettait à sa place.
Ensuite, il exécutait cette instruction modifiée
directement depuis le registre.
La fameuse boucle existait pour prendre en compte
ce temps supplémentaire d'exécution ---
au moment où cette instruction se terminait,
la prochaine se trouvait juste là où il fallait,
sous la tête de lecture du tambour.
Mais la boucle ne contenait aucun test.

L'éclair indispensable me vint lorsque je remarquai
que le bit de l'indice de registre,
le bit qui séparait la partie adresse de la partie
code opératoire dans le mot contenant l'instruction,
était positionné ---
or Mel n'utilisait jamais le registre d'indice,
le laissant tout le temps nul.
Lorsque je compris la lumière faillit m'aveugler.

Il avait localisé les données sur lesquelles il travaillait
près du haut de la mémoire ---
à des adresses à la limite de ce que pouvaient atteindre les instructions ---
et, après avoir traité la dernière donnée,
l'incrémentation de l'adresse dans l'instruction
la ferait déborder.
La retenue incrémenterait de un le code opératoire,
transformant cette instruction en
la suivante dans la gamme d'instructions :
une instruction de branchement.
Et, effectivement, la prochaine instruction se trouvait
à l'adresse zéro,
et le programme continuait tranquillement son chemin.

Je n'ai pas gardé de contact avec Mel,
je ne peux donc pas dire s'il a cédé à la vague
de changement qui a bouleversé les techniques de programmation
depuis cette époque lointaine.
J'aime à croire qu'il n'a pas cédé.
De toute manière,
j'avais été suffisamment impressionné pour abandonner ma
recherche de ce test malheureux,
en disant au Grand Chef que je ne pourrais le retrouver.
Il n'avait pas eu l'air surpris de la nouvelle.

Lorsque je quittai la compagnie,
le programme blackjack trichait encore
si on basculait le bon bouton,
et à mon avis c'est mieux comme cela.
Je me sentais mal à l'aise
à hacker le code d'un Vrai Programmeur.

Note Historique du Traducteur

Les premiers ordinateurs digitaux sont apparus vers la fin de la Seconde Guerre Mondiale. Ils se distinguaient des machines programmables qui les précédaient par leur capacité à stocker un programme en mémoire, et donc à modifier leurs propres instructions en cours d'exécution.

Les premiers ordinateurs utilisaient des tubes à vide (qu'on appelait également des lampes) comme élément logique. Ceux-ci ont été remplacés dans les années 1960 par les transistors, beaucoup plus petits, plus fiables et moins gourmands en consommation électrique. La mémoire des premiers ordinateurs était soit à base de lignes à retard de mercure, soit à base de tambours magnétiques rotatifs. Le temps d'accès à la mémoire à tambour du Harvard Mark III, par exemple, était de 17 millisecondes. Vers le milieu des années 1950 sont apparues les mémoires à tores de ferrite mentionnées dans le texte et dans lesquelles un bit était mémorisé par la position, nord ou sud, d'un petit tore magnétisé.

L'informatique a été révolutionnée par l'arrivée, vers la fin des années 1960, des circuits intégrés qui permettaient de placer beaucoup d'éléments logiques sur la même lame de silicium. Le premier microprocesseur (un circuit intégré à haute intégration) à rencontrer un succès commercial fut le 8080 de la jeune compagnie Intel, en 1974.

Ces énormes avancées technologiques ont entraîné des changements dans la manière de programmer les ordinateurs. La programmation en héxadécimal a vite été remplacée par l'utilisation d'assembleurs, puis de macro assembleurs. Les programmeurs se sont ensuite tournés vers des langages de plus haut niveau, tels que FORTRAN, Lisp et COBOL. Les années 1960 ont également vu l'apparition de systèmes d'exploitation, qui fournissaient des services de gestion des entrées-sorties et de système de fichiers, auparavant gérés en assembleur par chaque applicatif. Le premier grand système d'exploitation fut l'OS-360 du tout-puissant IBM en 196?. Unix a vu le jour au début des années 1970; il était le premier système d'exploitation populaire à offrir du multi-tâche. L'idiome Unix des petits scripts shell jetables est peut-être l'anti-thèse du style de programmation de Mel.

Bibliographie

Merci à Thierry Boudet et Eric Jacoboni d'avoir relu et corrigé cette traduction.