Introduction
Les trois types de
langage
Intentions et
conventions
I - Le langage machine
II - La gestation des
langages (1944-1954)
III -
Naissance du premier langage : Fortran (1957)
Conclusion
Introduction
Qui aujourd’hui, parmi les programmeurs,
sait qu’il fut une époque où seuls quelques praticiens concevaient l’utilité des
langages de programmation ? Tout le monde, ou presque, pensait alors que pour
programmer efficacement il fallait impérativement utiliser le langage machine.
Si en informatique l’intuition peine tant à
se former c’est que l’architecture des programmes, des systèmes d’information,
est invisible – ou plus précisément qu’elle ne peut apparaître qu’à travers
l’étroite fenêtre de l’écran, après un examen soigneux et beaucoup de réflexion.
L’expert se forge des convictions qu'il lui est difficile de partager avec ceux
qui n’ont pas examiné les choses d’aussi près que lui, et qui ne partagent donc
pas son expérience.
D’ailleurs on ne parle pas à un ordinateur,
on ne discute pas, on ne négocie pas avec lui : on le commande.
L’expression « langage de programmation » est donc un de ces faux amis qui
orientent l’intuition vers de fausses pistes : elle désigne en fait le
dispositif de commande de l’automate, c’est-à-dire une liste de termes
associés chacun à sa définition, couplée à une liste de règles selon lesquelles
organiser ces termes.
Les trois types de langage
On peut nommer « vocabulaire » la liste des
termes, « syntaxe » la liste des règles : il n’en reste pas moins une différence
entre ce dispositif de commande et les langages que nous autres êtres humains
parlons. L’économie des langages naturels est en effet celle de la suggestion
: le choix des termes et la construction des phrases élaborent le réseau de
connotations qui nous permet d’éveiller dans l’esprit de l’interlocuteur, avec
un minimum de paroles, l’image ou l’intention présentes dans le nôtre.
L’automate est par contre insensible à la suggestion comme aux connotations : un
programme informatique doit être parfaitement explicite.
Entre le langage naturel de la conversation,
de la littérature, et le langage de programmation s’intercale le langage de la
théorie (qu’elle soit mathématique, physique ou philosophique). En effet si les
concepts, inférences et relations de causalité que comporte une théorie doivent
être formellement explicites, on ne peut la comprendre véritablement que si l’on
adhère à l’intention qui a orienté le théoricien – et pour communiquer
une intention il faut recourir à la suggestion.
* *
Celui qui ne sait pas distinguer ces trois
types de langage trébuche sur des obstacles. Le « littéraire pur »,
exclusivement sensible aux connotations, peine à lire les textes théoriques :
dans un livre d’économie où alternent passages littéraires et passages
mathématiques, il faut, comme le skieur qui entre dans une neige plus
difficile, ralentir fortement la lecture quand on passe des uns aux autres. Le
« littéraire » peinera plus encore à lire un programme informatique car celui-ci
est écrit, quoiqu’en disent certains, non pour être lu par un être humain
mais pour être exécuté par l’automate.
Aux différences entre langage naturel,
langage théorique et langage de programmation répondent, dans notre action et
notre vie, des étapes différentes : le langage naturel est celui de la vie
quotidienne et de l’action immédiate ; le langage théorique est celui de la
réflexion, des anticipations, de la modélisation et de l’action différée ; le
langage de programmation enfin, de création récente, commande l’automate qui
assistera notre action et nos processus de production.
Ces trois langages sont
nécessaires chacun dans sa sphère propre et en outre ils communiquent : il
n’existe pas de théorie ni de programme qui ne réponde à une intention et
celle-ci ne peut s’exprimer que dans le langage naturel. Bien des erreurs, bien
des difficultés et des échecs s’expliquent par une confusion entre ces trois
types de langage, alors qu’ils cohabitent dans chaque entreprise, chaque
institution.
Ayant décrit leurs différences et suggéré
leur complémentarité, nous utiliserons l’expression « langage de
programmation » – elle appartient au lexique courant – mais nous saurons qu’il
faut, pour éviter les malentendus, la traduire par « dispositif de commande de
l’automate ». Nous dirons parfois même « langage » tout court pour alléger le
texte.
Intentions et conventions
Dans tout langage – qu’il soit naturel,
théorique, ou qu’il s’agisse d’un langage de programmation – on distingue des
caractéristiques logiques, que le raisonnement peut déduire à partir des
intentions de ses auteurs, et d’autres qui sont de pures conventions. Les noms que l’on donne
aux choses et aux êtres que le langage distingue sont conventionnels. Certaines
règles syntaxiques le sont aussi : dans un programme la fin d’une instruction se
note par un passage à la ligne (Fortran), un point virgule (C), la clôture d’une
parenthèse (Lisp) etc.
Dans l’apprentissage de tout langage la
mémorisation des conventions formelles accapare l’essentiel de l’effort
pédagogique qu'il s'agisse de l'acquisition du vocabulaire d’une langue naturelle, de la
nomenclature d’une théorie ou des règles d’un langage de programmation. La
compréhension des caractéristiques logiques du langage, par contre, suppose de
connaître les intentions des auteurs du langage ainsi que les obstacles et
outils auxquels ils ont été confrontés, toutes choses que les pédagogues
expliquent rarement.
Cependant les conventions, une fois
choisies, se solidifient en quelque sorte pour obéir à une logique qui sans être
celle du raisonnement n’en a pas moins ses règles, et que l’on peut qualifier d’étymologique.
Une langue naturelle évolue, par exemple, selon les lois de la phonétique. Tout nouveau langage de programmation reprend les conventions d’autres langages,
plus anciens, auxquelles ses créateurs se sont habitués. L’étymologie de
certaines notations de Java remonte ainsi à travers C++ jusqu’au langage C ; XML
descend de SGML à travers HTML.
Quels que soient l’âge et l’expérience, on
sera toujours un apprenti en matière de langage : ce que l’on ignore est
incomparablement plus vaste que ce que l’on connaît. Mais l’apprentissage est
facilité si l’on est psychologiquement prêt à accepter des conventions
inévitablement arbitraires, et si l’on est assez curieux pour partir à la
recherche des textes qui indiquent les intentions des créateurs. On peut enfin,
en s’intéressant à l’étymologie, trouver un ordre sinon une logique dans les
conventions elles-mêmes.
Ici nous entreprenons de décrire l’émergence
des langages de programmation. Nous nous appuierons pour cela sur le témoignage
de leurs créateurs. Ils décrivent leurs intentions, les obstacles qu’ils ont dû
surmonter ; nous découvrirons l’origine de termes qui, comme « compilateur »,
font aujourd’hui partie du langage courant.
* *
Les langages de programmation, dénommés
aussi langages de haut niveau, ont été bâtis pour surmonter les
difficultés que le langage de la machine (ou « langage machine ») oppose à
l’être humain : il faut donc partir du langage machine pour faire ressortir ces
difficultés et la nécessité de langages plus commodes.
I - Le langage machine
Au cœur de l’ordinateur résident un
processeur et une mémoire, autrement dénommée « mémoire vive » ou « Random
Access Memory », RAM.
Tout le travail de l’automate se déroule entre le processeur et la mémoire, le
programme commandant par ailleurs les échanges avec des périphériques (écran,
clavier, disque dur, etc.).
Avant tout travail le programme et les
données sont chargés dans la mémoire sous la forme d’une suite de 0 et de 1
concrétisés par deux niveaux différents de tension électrique. Le
processeur reçoit du programme des instructions codées en binaire qu’il exécute l’une après
l’autre. Il dispose de registres pour stocker et traiter une instruction,
les adresses des données auxquelles elle s’applique et les données elles-mêmes.
Chaque instruction obéit à une structure
simple : un code pour l’opération (additionner, soustraire, multiplier, diviser,
changer de signe etc.), un code pour chacune des adresses qu’ont dans la mémoire
les données concernées par l’opération, un code pour l’adresse où il faudra
inscrire le résultat.
La vitesse d’un processeur se mesure en MIPS
(millions d’instruction par seconde). Considérons une opération des plus
simples, comme déplacer le curseur en fin de ligne lors de la saisie d'un texte.
Si nous utilisons un raccourci clavier cette action se traduira par environ 20 000 instructions élémentaires. Si le processeur a
une vitesse de 500 MIPS, exécuter 20 000 instructions lui demande une toute petite
fraction (4 % exactement) de microseconde.
Cet exemple illustre ce qui distingue la
physique de l’automate, qui traite à toute vitesse des instructions écrites en
binaire, de la physique de sa programmation et de celle de son utilisation. Se
servir d’un raccourci clavier pour donner un ordre à l’ordinateur, c’est tout
simple et 4 % de microseconde est pour un être humain un délai très court. Cela
déclenche cependant dans le processeur une avalanche d’instructions qu’il serait
fastidieux de programmer : on conçoit le besoin de traduire automatiquement les
ordres de l’utilisateur en instructions élémentaires. Les interpréteurs, les
compilateurs et le système d’exploitation ont été progressivement conçus pour
répondre à ce besoin.
Les tout premiers programmes étaient
cependant codés en binaire et contenaient toutes les instructions élémentaires.
Les écrire était très pénible : l’être humain mémorise difficilement des codes en
binaire et les programmes écrits de la sorte sont pour lui pratiquement illisibles.
Un premier progrès a consisté à organiser
les bits en octets et à écrire les instructions en octal, un interpréteur
traduisant ensuite les octets en bits pour produire le programme exécutable.
Mais des codes numériques restent difficiles à mémoriser et à lire : les
assembleurs ont permis de coder les instructions en caractères
alphabétiques.
Bits, octal et assembleur
Voici une instruction telle qu’elle se présente au processeur :
011011 000000 000000 000000 000001 000000
Transcrite en octal, elle prend la forme :
27 0 0 0 0 64
et enfin en assembleur :
CLA 0 0 0 0 64
Un programme en assembleur sera plus lisible
pour un être humain que ne l’est le
programme en octal ou, pis, le programme exécutable auquel il équivaut, il sera
donc plus facile de le vérifier et de le corriger. Mais il
code explicitement chacune des instructions élémentaires :
sa seule différence avec le code exécutable réside dans la façon dont
l’instruction élémentaire est écrite. L’assembleur est donc identique, à une
interprétation simple près, au langage de la machine : il ne mérite pas le
nom de langage de programmation .
Les premiers programmeurs, ceux des années
1940 que l’on nommait d’ailleurs « codeurs »,
codaient en octal. Les langages de programmation n’ont émergé que très
difficilement car leurs promoteurs ont dû surmonter des préjugés : l’opinion
commune était alors que l’on ne pouvait coder qu’en octal.
Le premier langage de programmation digne de
ce nom a été Fortran, publié en avril 1957. Cette réalisation étonnante a été
préparée par une longue période de gestation lors de laquelle furent
progressivement conçus les outils sur lesquels s’appuie un langage
(interpréteurs, compilateurs, systèmes d’exploitation), et définies les
exigences auxquelles il doit répondre.
II - La gestation des langages (1944-1954)
Nous disposons d’un témoignage précieux :
l’exposé introductif de Grace Hopper,
un des tout premiers « codeurs », à la conférence sur l’histoire des langages de
programmation (HOPL) organisée par l’ACM en 1978.
Nous en reprenons ici certains éléments.
* *
Après son entrée dans la marine en 1943
Grace Hopper est chargée de produire des programmes pour le Mark I, précurseur
des ordinateurs modernes. En 1949, elle programme le premier compilateur, A-0,
qui aura pour successeurs A-1 et Math-Matic. En 1955, elle spécifie le langage
Flow-Matic, contribution majeure au Cobol dont elle supervisera aussi le
développement.
Grace Hopper dit avoir passé 20 ans à se
battre contre l’« establishment ». Dans les premières années de l’informatique,
tout le monde pensait que l’on ne pouvait programmer un ordinateur qu’en octal.
Puis quelques rares personnes ont admis que l’on puisse programmer en
assembleur…
Le Mark I disposait de programmes câblés
dans la machine pour calculer des sinus, exponentielles etc. mais ces programmes
étaient trop généraux. Les codeurs avaient besoin de méthodes finement adaptées
à chacun des problèmes qu’ils traitaient. Ils avaient commencé à programmer des
fonctions (subroutines). Si un codeur devait calculer le sinus d’un angle
inférieur à 45° il appelait un collègue, lui demandait sa fonction sinus puis la
copiait dans son cahier. Les codeurs ont fini par voir qu’il fallait disposer
d’un format général pour copier les fonctions, et Grace Hopper l’a écrit pour le
Mark I. Ainsi dès 1944 les codeurs ont disposé d’un premier outil pour
programmer mieux et plus vite.
La communication était rare alors entre les
informaticiens, sinon par le canal de relations personnelles. Pendant quelques
années, chacun a dû pratiquement tout inventer pour lui-même. La toute première
réunion sur la programmation s’est tenue à Harvard en 1948. En 1951 la Navy
inaugura une série de trois séminaires sur le codage, la programmation
automatique etc. (le mot software n’existait pas encore). Quelques
articles ont effleuré la question de la programmation mais il n’existait pas de
réelle assistance pour écrire des programmes.
Les Britanniques Wheeler, Wilkes et Gill ont
cependant publié un livre montrant qu’ils avaient conçu, avant même de
construire l’ordinateur, une bibliothèque de fonctions aux interfaces
d’entrée-sortie standardisées. Une telle bibliothèque permettait de programmer
un peu plus vite.
* *
En 1949 le Short Order Code de John
Mauchly a permis au Binac de travailler en décimal et en virgule flottante.
Short Code utilisait des mots de deux caractères numériques : un mot
représentait « X », un autre le signe « égale », un autre « a », un autre « + »,
un autre « b ». Les fonctions étaient stockées dans la mémoire et le code
contenait des références symboliques aux fonctions. C’était un langage
interprété : le programme lisait chaque instruction, sautait jusqu’aux fonctions
qu’elle appelait, les exécutait, puis allait à l’instruction suivante. Il ne
fournissait pas un véritable code objet. Nous dirions aujourd’hui que c’était
une machine virtuelle, et pour les codeurs c’était un pseudo code
implémenté à travers un programme.
Le Short Code a fait comprendre à
Grace Hopper qu’il était possible de programmer autrement qu’en langage machine.
Le Sort-Merge Generator de Betty Holberton la convainquit que l’on
pouvait utiliser l’ordinateur pour écrire des programmes : on introduisait les
spécifications des fichiers et le Sort-Merge Generator produisait un
programme de tri et de classement ainsi que la gestion des entrées-sorties sur
les lecteurs de bande. Il contenait une première version de mémoire virtuelle
car il gérait les pages automatiquement.
* *
L’« establishment » estimait cependant qu’un
ordinateur, n’ayant ni l’imagination ni l’habileté d’un être humain et ne
sachant faire que de l’arithmétique, serait à tout jamais incapable d’écrire un
programme. Grace Hopper soutint par contre dès 1952 que l’on pouvait programmer
tout ce qu’il était possible de définir complètement, et que l’on pourrait ainsi
incorporer l’habileté humaine dans un générateur.
A l’automne 1951 on lui demanda de
construire pour l’Univac I une bibliothèque de fonctions suffisamment
standardisée pour que tout le monde puisse s’en servir. Les
programmeurs utilisaient alors des fonctions, les copiaient d’un programme à
l’autre, mais elles démarraient toutes à la ligne 0 puis continuaient
séquentiellement : quand on les copiait dans un autre programme il fallait
additionner toutes ces adresses. En outre les programmeurs faisaient des erreurs
quand ils copiaient un programme : un 4 se transformait parfois en un delta, un
B en 13 etc. Mieux valait faire copier les fonctions par l’ordinateur : c'est
ainsi que naquit le A-0 que Grace Hopper programma entre octobre 1951 et mai
1952. Il a été nommé « compilateur » parce qu’à chaque fonction était associé
une appellation et que les fonctions étaient dans une bibliothèque : or quand on
extrait des documents d’une bibliothèque on dit qu’on les « compile ».
L’A-0 n’était ni un langage, ni ce que l’on
appellerait aujourd’hui un compilateur, mais une série d’appels de fonctions
associées chacune à ses arguments. Il ne comportait aucune optimisation : il
s’agissait d’écrire rapidement des programmes de calcul qui ne seraient utilisés
qu’une fois, et d’obtenir rapidement un résultat. Grace Hopper l’a soigneusement
documenté parce que personne ne croyait qu’il puisse fonctionner.
Son argument était le suivant : on utilisait des fonctions dûment vérifiées et
on les assemblait avec un programme automatique lui aussi vérifié ; les seules
erreurs que le programmeur puisse faire étaient donc des erreurs de logique.
Le Mark I pouvait faire trois additions par
seconde avec des nombres de 23 chiffres. C’était alors la machine la plus
fantastique qui ait jamais été construite ! Mais l’Univac I faisait 3 000
additions par seconde. Il avalait les programmes à toute vitesse, alors que les
programmeurs n’avaient pas accéléré au même point : il fallait donc trouver le
moyen de programmer plus vite. Par ailleurs de plus en plus de gens voulaient
résoudre des problèmes mais répugnaient à coder en octal et à manipuler des
bits.
Le but des premiers informaticiens n’était
pas de concevoir un langage de programmation. Ils étaient indifférents aux
virgules et points-virgules mais voulaient écrire plus vite des programmes
corrects et répondre plus vite aux besoins – y compris à ceux des ingénieurs,
des commerciaux et pas seulement à ceux des programmeurs. Il leur fallait aussi
s’adapter à diverses formes d’intuition : certains préfèrent les notations
symboliques, d’autres les notations proches du langage naturel. Il ne convenait
pas de contraindre tout le monde à se plier au formalisme mathématique.
En novembre 1952 apparut l’Editing
Generator de Millie Coss. Le traitement de texte était pour les programmeurs
un problème délicat : pour introduire des mots, des points, des « $ », pour
supprimer des zéros, il leur fallait tout faire à la main. Comme ils savaient
quel format ils voulaient donner à leurs programmes, il leur était utile de
disposer d’un générateur de texte. Editing Generator prenait le format du
fichier, le format des enregistrements, le format du document de sortie, puis
produisait le code pour passer de l’un à l’autre.
Cependant l’écriture des spécifications en
A-0 était lourde. Chaque instruction était un mot de douze caractères
alpha-décimaux comportant trois adresses : les trois premiers caractères
désignaient une opération, les trois suivants une donnée, puis venaient trois
autres pour une autre donnée et enfin les trois derniers pour le résultat. Les
programmeurs s’y étaient tellement habitués qu’ils croyaient que le monde entier
raisonnait ainsi. En superposant ce codage à l’A-0 à l’aide d’un traducteur et
en ajoutant des fonctions pour traiter les entrées-sorties Grace Hopper a obtenu
le compilateur A-2.
Ce langage a permis de programmer le calcul
différentiel. Tout le monde disait que c’était impossible parce que « les
ordinateurs ne sont pas capables de faire autre chose que de l’arithmétique ».
Il a fallu « vendre » l’A-2 non seulement aux utilisateurs mais aussi aux
managers, et convaincre ces derniers qu’il était rentable de mettre au point des
fonctions qui aideraient à programmer. A la fin de 1953 les utilisateurs étaient
satisfaits de l’aide que l’A-2 leur apportait, mais il restait « évident » dans
la profession qu’il était plus efficace de programmer en octal.
En 1954 furent enfin publiées les
spécifications de Fortran, premier vrai langage de programmation. On
n’aurait pas pu concevoir Fortran si l’on n’avait pas conçu auparavant le
générateur, le compilateur et les autres outils pour réaliser des langages.
* *
Les méthodes qui conviennent pour construire
un langage de type mathématique ne conviennent pas pour produire un langage de
traitement des données.
Si en mathématiques tout le monde sait ce
qu’est un sinus, il n’existait pas de vocabulaire commun pour le traitement des
données. L’équipe de Grace Hopper a analysé 500 programmes de traitement de
données et identifié 30 verbes qui lui semblaient être les opérateurs du
traitement de données.
On peut écrire les programmes mathématiques
dans un langage mathématique, mais il faut écrire les programmes de traitement
des données dans une langue naturelle. L’establishment déclara que c’était
impossible parce que les ordinateurs ne pourraient pas comprendre l’anglais ;
Grace Hopper répondit qu’elle n’avait jamais pensé qu’ils le puissent, qu’il
s’agissait simplement de comparer des suites de bits.
Elle publia en janvier 1955 un projet de
compilateur pour le traitement des données. Le langage – un pseudo code – était
composé de mots anglais de longueur variable séparés par des espaces et de
phrases terminées par des points. Pour pouvoir convaincre, elle décida de
construire un prototype. Il fallait gérer des listes d’opérations, de fonctions,
de sauts, de stockage. Les managers ne comprenaient pas ce qu’est une liste :
elles furent baptisées « fichiers » et l’obstacle fut levé.
Le prototype ne pouvait contenir que 20
instructions et cela paraissait peu pour demander un gros budget. Alors les
programmeurs ont remplacé les mots anglais par des mots français, puis
allemands. Les managers ont été impressionnés ! Il était évident pour eux qu’un
ordinateur américain ne pourrait jamais « comprendre » le français, ni
l’allemand, pourtant il le faisait. En fait, ce « langage » n’était pas un vrai
langage mais seulement un code. Ce qui était pour les programmeurs une simple
substitution de bits avait cependant fait faire à l’ordinateur une chose que les
managers avaient jugée impossible : pénétrer le territoire des langues
étrangères. Des choses très simples pour le programmeur semblent aux managers
venir d’un autre monde.
Ce compilateur fut nommé Flow-Matic. Comme
la mémoire ne comportait que 1 000 mots il fallait deux heures pour compiler un
programme tandis que les lecteurs de bande tournaient à toute allure.
Un langage n’est pas très utile s’il fournit
des résultats différents selon la machine : à la fin des années 60 la Navy
souhaitait que tous les compilateurs Cobol fournissent le même résultat, quelle
que soit la machine utilisée. Grace Hopper fut chargée de concevoir des
programmes pour valider un compilateur Cobol en contrôlant son fonctionnement et
en comparant ses résultats aux résultats standards. Pour la première fois, on
utilisait ainsi un programme pour vérifier un autre programme.
III - Naissance du premier langage : Fortran
(1957)
Les origines de Fortran ont été décrites par
John Backus,
son créateur. De façon significative, il accorde plus d’importance à la
conception du compilateur qu’à celle du langage lui-même.
* *
Avant 1954 presque tous les programmes
étaient écrits en langage machine ou en assembleur. La programmation était
considérée comme un art complexe, créatif, et on croyait l’imagination humaine
indispensable pour écrire des programmes efficaces. L’essentiel des difficultés
provenait des limitations des ordinateurs de l’époque : ils n’avaient pas de
registres d’index, les opérations en virgule flottante n’étaient pas câblées
dans la machine, les jeux d’instructions étaient limités (ils avaient par
exemple un AND mais pas un OR), les entrées-sorties étaient primitives. La
programmation automatique (automatic programming) visait à surmonter ces
obstacles à l’aide d’adresses symboliques et de nombres décimaux.
La plupart des systèmes de programmation
automatique, comme par exemple le compilateur A-2, fournissaient un ordinateur
synthétique avec un code d’opérations différent de celui du langage machine, le
calcul en virgule flottante, des registres d’index et des commandes
d’entrée-sortie. Mais les instructions de l’A-2, au lieu de s’écrire dans un
pseudo code commode, étaient des séquences compliquées d’« instructions de
compilation » sous diverses formes, du code machine lui-même jusqu’à de longs
groupes de mots ou des instructions abrégées qui devaient être traduites en
instructions de compilation.
Le langage algébrique de Laning et Zierler
était simple et élégant. Il identifiait les variables avec un caractère et un
indice, et les fonctions par la lettre « F » suivie d’un exposant numérique
indiquant son numéro. Quand on utilisait ce langage le temps d’exécution était
multiplié par dix.
Pour la plupart des programmeurs « automatic
programming » signifiait simplement de fournir des codes pour les opérations
et des adresses symboliques ; pour d’autres il s’agissait de puiser des
fonctions dans une bibliothèque et d’insérer dans chacune d’entre elles les
adresses des opérandes.
Ces systèmes de programmation automatique
divisaient la vitesse de la machine par un facteur cinq à dix. L’essentiel du
temps était accaparé par le traitement en virgule flottante. Simuler
l’indexation et d’autres opérations de type « administratif » pouvait se faire
en utilisant des fonctions peu efficaces car quoique très lentes elles
demandaient beaucoup moins de temps que le travail en virgule flottante.
Les limitations de ces systèmes avaient
convaincu les programmeurs qu’il était impossible d’automatiser efficacement la
programmation. En outre certains gourous avaient prétendu offrir des systèmes
capables de comprendre le langage humain ainsi que les besoins des utilisateurs
mais ces systèmes s’étaient révélés à l’usage incommodes et inefficaces, limités
qu’ils étaient à quelques tâches administratives et en outre remplis
d’exceptions.
Dans un centre informatique, le coût de la
programmation était du même ordre que le loyer de l’ordinateur. De surcroît le
quart ou la moitié du temps d’ordinateur était accaparé par le déboguage. Ainsi
la programmation et le déboguage représentaient les trois quarts du coût de
l’informatique et cela allait empirer si le prix des ordinateurs diminuait.
C’est pourquoi John Backus a proposé à IBM à la fin de 1953 de lancer le projet
Fortran.
*
*
L’arrivée de l’IBM 704, avec les virgules
flottantes et les index en dur, changea entièrement la situation. Il supprimait
la raison d’être des anciens systèmes et, en accélérant les calculs en virgule
flottante, ne laissait plus aucune place où cacher les inefficacités.
Compte tenu du scepticisme dominant envers
la programmation automatique et de l’impossibilité de cacher désormais les
inefficacités, Backus était sûr que le système auquel il pensait ne pourrait
être accepté que s’il était prouvé qu’il fournissait des programmes au moins
aussi efficaces que ceux qui avaient été programmés à la main. Le plus grand
défi lui semblait ainsi résider non dans la conception du langage mais dans la
programmation du compilateur (ou, comme on disait alors, du traducteur).
Bien sûr l’un de ses buts était de concevoir
un langage qui permettrait à des ingénieurs et des scientifiques de programmer
eux-mêmes pour le 704. Il voulait aussi éliminer les tâches administratives, la
planification répétitive et détaillée qu’implique un codage à la main. Il
fallait permettre les affectations (assignment statements), les variables
indexées et l’instruction DO.
Ignorant tout des difficultés de la
conception des langages qui sont apparues plus tard (structure de blocs,
expressions conditionnelles, déclarations de type), il estimait avoir défini une
bonne base pour le langage : tout ce qui a émergé d’autre par la suite est
apparu progressivement. Il espérait aussi que Fortran appliquerait
automatiquement des techniques laborieuses mais efficace de codage qu’un
programmeur humain n’aurait ni le temps, ni le l’envie d’utiliser.
A la charnière de 1954 et de 1955 l’équipe
qui préparait Fortran a tenu des conférences avec les utilisateurs pour les
informer du projet et s’enquérir de leurs objections et besoins. Ces conférences
n’ont pas servi à grand-chose : les utilisateurs avaient entendu trop de
descriptions enthousiastes de systèmes qui les avaient déçus par la suite et ils
ne prenaient pas ce projet au sérieux. En particulier, ils ne croyaient pas
qu’il soit possible de produire automatiquement un programme efficace.
* *
Le travail sur le compilateur a commencé au
début de 1955. L’équipe avait d'abord défini le code en langage machine traduisant
diverses expressions en langage source.
Le travail fut organisé d’abord en trois
sections auxquelles il fallut par la suite en ajouter trois autres. Chaque
section était réalisée par un groupe de deux ou trois personnes qui développait
ses programmes et s’assurait de leur compatibilité avec ceux des sections
voisines.
La section 1 devait lire la totalité
du code source, compiler ce qu’elle pouvait (opérations arithmétiques,
entrées-sorties) et classer le reste dans des tables appropriées. Les opérations
arithmétiques furent ainsi optimisées et les entrées-sorties furent codées sous
la forme d’une série d’instructions DO.
La section 2 devait analyser la
structure du programme afin de produire un code optimisé à partir des
instructions DO et des références aux données indexées, ce qui impliquait de
traiter une grande diversité de cas particuliers. Cette section a fourni un code
dont l’efficacité a surpris les programmeurs qui l’examinaient.
Le 704 n’ayant que trois registres d’index,
il apparut rapidement qu’il ne serait pas facile de le programmer de façon
optimale. Backus a donc décidé de faire comme si l’ordinateur disposait d’un
nombre infini de registres d’index et de remettre à plus tard la réduction de ce
nombre à trois. Cela l’a conduit à créer deux sections nouvelles, 4 et 5 (la
section 3 fut ajoutée pour donner au produit des sections 1 et 2 la forme
requise par les sections 4 et 5).
La section 4 devait diviser le
programme produit par les sections 1 et 2 en blocs ne contenant aucun
branchement, puis faire par simulation une analyse statistique de la fréquence
d’exécution de chaque bloc et rassembler l’information sur l’utilisation des
registres d’index.
La section 5 devait transformer le
programme en ramenant à trois le nombre des registres d’index. Avec la section 2
c’était la section la plus compliquée et elle a eu une grande influence sur la
conception des compilateurs ultérieurs.
Enfin la section 6 assemblait le
résultat sous forme binaire et y introduisait le code des fonctions puisées dans
la bibliothèque.
La compilation introduisait dans le
programme des changements qui le rendaient plus efficace mais auxquels on
n’aurait jamais pensé. La transformation était si radicale que les programmeurs
croyaient parfois que le compilateur avait fait une erreur – mais après une
étude approfondie ils constataient qu’il était correct. Parfois le programme
était complètement réorganisé pour économiser une instruction. Dans certains
contextes une même instruction DO pouvait ne produire aucune instruction, alors
que dans d’autres contextes elle produisait un grand nombre d’instructions à
divers endroits du programme.
Après avoir publié Fortran en avril 1957
l’équipe s’est occupée de son déboguage jusqu’à la fin de l’été. Un flot de
lettres, télégrammes et appels téléphoniques venant des utilisateurs lui apportait des problèmes.
En avril 1956, plus de la moitié des centres informatiques équipés de 704
utilisaient Fortran pour réaliser plus de la moitié de leurs travaux.
En automne 1957 l’équipe a commencé le
travail pour traiter des problèmes qu’elle avait laissés d’abord de côté et corriger certaines lacunes : il fallait introduire de meilleurs outils de
diagnostic, des commentaires plus clairs, et permettre à l'utilisateur de définir de nouvelles
fonctions. Cela conduira à Fortran II au printemps de 1958. Cependant la durée
de la compilation restait excessive et le déboguage prenait beaucoup de temps :
c’était le principal défaut de Fortran II, et les versions ultérieures du langage
ont tenté de le corriger.
Conclusion
Après 1957, de nombreux autres langages ont
été conçus, répondant à des finalités diverses. Les langages se sont
diversifiés, certains comme Lisp semblant appartenir à un tout autre monde que
Fortran. En 1967 Sammet en a dénombré 120 dont 20 étaient morts ou obsolètes, 35
étaient peu utilisés, 50 étaient spécialisés dans un domaine d’application, 15
enfin étaient largement utilisés.
Aujourd’hui, la descendance de Fortran dessine une arborescence d’une grande
complexité ; à coup sûr il est plus difficile de suivre la filiation
étymologique de ces divers langages que de saisir l'arbre par la racine et
décrire son émergence.
|