Page d'accueil de ce livre
Chapitre 4 Le travail informatique
1 De la nature de l'informatique
Premières croyances
Les premiers ordinateurs, qui entrèrent en fonction à l'extrême fin
des années 1940 et durant les années 1950, étaient consacrés à des
travaux militaires ou scientifiques puisque, à cette époque, on pensait
qu'ils seraient utiles essentiellement aux calculs des physiciens. Le
projet phare de ces années fut SAGE (Semi-Automatic Ground
Environment), système de traitement des données issues des radars
de défense anti-aérienne, destiné à prémunir les États-Unis contre une
attaque nucléaire soviétique, dont le coût final atteignit huit
milliards de dollars de l'époque. D'autres projets militaires d'une
ampleur comparable permirent la naissance et l'expansion d'une
population de professionnels de la programmation des ordinateurs et,
au bout du compte, l'apparition d'une véritable industrie du logiciel,
bien décrite par Martin Campbell-Kelly
[21]. Cet afflux de financements militaires joua
un rôle de premier plan dans l'élan initial de l'industrie
informatique américaine.
Il ne fait aucun doute que lors de ces premières réalisations
informatiques la part du logiciel fut considérablement sous-estimée
tant sur le plan financier que sur ceux de la durée et de la
complexité du travail à accomplir. On s'imaginait en être quitte avec
quelques dizaines de lignes de langage machine
écrites sur un coin de table pour faire marcher les ordinateurs qui,
eux, exhibaient les signes extérieurs de leur prix élevé en pesant des
dizaines de tonnes et en consommant des centaines de kilowatts-heure
d'électricité. Aussi les dépassements de coûts et de délais furent-ils
la règle et engendrèrent-ils frustrations et déceptions ; c'est
d'ailleurs encore le cas aujourd'hui.
Les premiers programmeurs étaient des scientifiques recrutés pour
leurs compétences en analyse numérique et en algèbre linéaire,
puisqu'il s'agissait essentiellement, croyait-on, de résoudre des
équations différentielles et d'inverser des matrices. Ces problèmes
mathématiques furent d'ailleurs résolus sans soulever de difficultés
insurmontables, même si l'application de l'informatique aux problèmes
numériques reste un domaine de recherche actif, et le restera tant que
les physiciens continueront à inventer de nouvelles équations pour
modéliser de nouveaux problèmes. Ce qui est erroné n'est donc pas
d'attribuer à ces problèmes de numériciens une place dans la science
informatique, c'est d'imaginer cette place comme centrale et
absolument décisive. Une conséquence éminemment visible de cette
erreur se donne à voir en France (terre particulièrement affectée par
elle) où le principal institut public de recherche en informatique a
été animé, puis dirigé, de sa création en 1967 jusqu'à
la fin de l'année 2003 par des numériciens purs qui avaient de
l'informatique une vision très unilatéralement mathématique et
numérique, pour ne pas dire très peu informatique.
Comment l'informatique diffère des mathématiques
J'aimerais à l'occasion de cette analyse attirer l'attention du
lecteur sur une question qui est une source constante de malentendus
au sujet de la programmation.
Il y a fort longtemps, à l'INSEE, un de mes collègues informaticiens
débattait avec un statisticien, issu d'une grande école scientifique
de la République, d'un projet informatique que le premier aurait à
réaliser pour le second. L'informaticien expliquait le délai
nécessaire à ce projet par la longueur des développements, due
notamment à la nécessité de procéder à des essais pour éliminer les
erreurs qui se seraient glissées dans les programmes.
Cette démarche scandalisait le statisticien : « Quand je résous une
équation différentielle, » disait-il, « je ne fais pas d'erreur,
pourquoi en commettez-vous dans vos programmes ? ». L'auteur pourrait
simplement rétorquer, d'expérience personnelle, qu'il arrive que l'on
commette des erreurs en résolvant des équations différentielles, mais
en fait la question n'est pas là. La démarche du calcul mathématique,
pour qui en a acquis une maîtrise suffisante pour tel ou tel type de
problème, comporte dans son déroulement même un dispositif
d'auto-vérification. L'enchaînement des égalités qui conduisent à la
solution obéit à des règles formelles et précises telles que les
erreurs doivent, en principe, sauter aux yeux. L'imagination
intervient dans l'élaboration de l'expression qui va faire progresser
le calcul, et c'est pour cela que la résolution des problèmes
mathématiques ne peut pas être confiée à un automate, fût-il un
ordinateur, mais une fois cette expression rédigée et écrite au
tableau, sa capacité à vérifier la relation d'égalité avec
l'expression précédente est, pour quelqu'un qui s'y connaît,
immédiatement perceptible.
Les preuves de programme
L'écriture de programmes informatiques obéit à de tout autres
principes. Il convient de préciser cette affirmation pour la préserver
d'une réfutation facile : du fait de sa naissance dans un milieu
fortement influencé par le calcul mathématique, l'informatique a
connu, et connaît encore, une activité assez intense de théoriciens
qui entendent développer ce que l'on appelle des méthodes de preuve
formelle, destinées à conférer à l'écriture de programmes la même
capacité auto-vérificatrice que les équations mathématiques sont
censées posséder. La recherche dans le domaine de la démonstration
automatique de théorèmes n'a jamais cessé d'être active. Il serait
erroné de nier l'influence notable que ces recherches ont exercée sur
l'orientation prise, notamment, par la conception des langages et des
outils de programmation. Mais le programme que chacun utilise
quotidiennement pour écrire son courrier ou son livre, naviguer sur le
WWW, faire la comptabilité de son entreprise ou jouer sur sa console
de jeux a selon toute vraisemblance été écrit par des programmeurs qui
n'en avaient même jamais entendu parler. Ce serait peut-être moins
vrai pour le logiciel qui pilote Ariane V ou une centrale nucléaire,
sans d'ailleurs que cela garantisse le moins du monde l'absence
d'erreurs de programmation, l'expérience le prouve. En fait, de tels
logiciels comportent un si grand nombre de lignes de texte (un
programme, c'est un texte) qu'il serait irréaliste d'en entreprendre
la preuve, si tant est que ce soit possible ; on se contente d'essayer
de « prouver » les parties jugées les plus critiques, quitte à
s'apercevoir plus tard, lorsqu'une erreur survient et amène la
destruction d'Ariane V et de sa charge utile, que la criticité n'était
pas là où on l'attendait... et l'erreur pas dans le
logiciel[62]. Bref, le logiciel, par nature, comporte
des erreurs, encore et toujours. Nous aurons néanmoins l'occasion
d'évoquer des méthodes réalistes de spécification formelle de
programmes sûrs, par exemple à la page ?? consacrée à la
méthode B, et au chapitre 8 qui abordera les projets
d'informatique industrielle et technique.
Si les auteurs de programmes réels ignorent les méthodes de preuves
formelles, ce n'est pas toujours par incompétence ou négligence : ces
méthodes sont souvent inadaptées à leur travail, nombre d'entre elles
ont été imaginées par des théoriciens universitaires très éloignés de
leur pratique. Il ne fait aucun doute qu'un rapprochement entre ces
deux démarches serait fructueux pour les uns et pour les autres, mais
aujourd'hui en France cela ne peut arriver qu'exceptionnellement pour
deux raisons : l'informatique universitaire y est dominée par des
mathématiciens réformés surtout désireux de ne jamais avoir affaire à
un ordinateur, d'autre part l'accès aux formations professionnelles
informatiques est artificiellement limité par des effectifs insuffisants
et par des exigences excessives de niveau en mathématiques, ce qui a
pour conséquence qu'une grande proportion des professionnels de
l'informatique ne possède pas de diplôme et n'a qu'une formation
acquise sur le tas ou auprès des fournisseurs, c'est-à-dire totalement
dépourvue de bases théoriques.
Cette situation évolue depuis quelques années : la méthode B a commencé
à obtenir des résultats convaincants. L'équipe LogiCal, qui associe des
chercheurs de l'INRIA (Institut National de Recherche en Informatique et
en Automatique) et du Laboratoire de Recherche en Informatique
d'Orsay (LRI), a développé le logiciel Coq, un « assistant
de preuve » prometteur doublé d'un langage de programmation sûr.
2 Programmation dans le monde réel
La vraie nature de la programmation des ordinateurs
Alors, comment s'écrivent les programmes informatiques ? Et
d'ailleurs, qu'est-ce qu'une erreur de programmation ?
Ces questions sont liées et elles sont, bien sûr, au coeur de notre
préoccupation.
Si les énoncés des mathématiques sont auto-vérifiables, ou en tout cas
nettement plus vérifiables que les énoncés du langage humain courant,
c'est par la vertu de la méthode axiomatique, qui place au fondement
de chaque théorie mathématique un corpus d'axiomes que les nouvelles
propositions de la théorie devront respecter, et d'un formalisme
rigoureux garantissant la solidité d'une démarche qui progresse
d'hypothèses en conclusions par des transitions claires et sans
ambiguïtés. Enfin, en principe. Kurt Gödel et
d'autres ont montré les limites de cette méthode, qui n'en
prête pas moins aux assertions des mathématiciens des fondations d'une
exceptionnelle solidité, dans les limites de la théorie, s'entend.
Pour expliciter la démarche mathématique, les logiciens du XXe
siècle ont élaboré la notion de système formel, déjà suggérée
par Leibniz plus de deux siècles
auparavant. C'est important pour notre propos, parce que si les
systèmes formels ont eu un succès modéré auprès des mathématiciens qui
affectent le plus souvent de négliger cette question des fondements,
ils sont à l'origine de la théorie des ordinateurs. En voici la
définition empruntée à l'encyclopédie Hachette Multimédia en
ligne sur Yahoo[] :
« Le système formel est une notion logique fondamentale issue du double
effort de constituer une logique mathématique et d'axiomatiser les
théories mathématiques usuelles. Cet effort procède d'un idéal de
rigueur --- éviter les recours non contrôlés à l'intuition,
expliciter toutes les hypothèses effectivement utilisées dans un
raisonnement, par exemple --- qui s'est diversement affirmé à
partir de la fin du XIXe siècle. Les travaux de Frege, de Dedekind,
de Peano, de Hilbert, de Whitehead et Russell, de Gödel jalonnent
brillamment cet effort. Ils contribuent à mettre au centre de
l'intérêt des logiciens l'analyse de l'idée de démonstration, ou,
comme on dit encore, de déduction, de dérivation ou d'inférence. »
Nous pourrions ajouter à cette liste de logiciens l'Argentin Alonzo
Church, créateur du l-calcul, formalisme
destiné à l'étude des fonctions mathématiques et qui a engendré le
langage de programmation Lisp. Un disciple britannique de Church, Alan
Turing, a cherché à préciser la nature des
procédures effectives de Gödel, qui disait qu'un système était
décidable s'il existait une procédure effective pour distinguer les
propositions démontrables des autres. Inventer une procédure
effective (un algorithme) consiste à déterminer un enchaînement
d'opérations élémentaires qui exécuteront les calculs nécessaires à la
solution d'un problème pour lequel existe une solution calculable (il
y a des problèmes sans solution et des solutions incalculables). Une
procédure effective doit recevoir une définition finie, et chacune de
ses étapes doit pouvoir être exécutée mécaniquement. Pour clarifier
cela, Turing a défini en 1936 le modèle théorique nommé machine
de Turing, laquelle forme depuis lors avec le l-calcul la
base de la théorie des langages de programmation. Enfin le Hongrois
naturalisé américain John von Neumann a
élaboré en 1945 à partir de ces travaux théoriques le modèle concret
de l'ordinateur, encore valable aujourd'hui et connu sous le nom
d'architecture de von Neumann.
La science de la programmation des ordinateurs, qui constitue le
coeur de l'informatique, est donc déterminée par un lien de
filiation avec les mathématiques, ou plutôt (la nuance a son poids)
avec l'étude logique des opérations des mathématiques. Le champ de
cette étude logique qui a engendré l'informatique est organisé autour
de la notion de procédure effective, dont le propos est de
cerner précisément la suite des opérations concrètes par lesquelles
s'effectue un calcul1 ; ou, pour déjà
parler informatique, la suite des opérations qui à partir de certaines
données produiront certains résultats, constituant ainsi
un traitement.
C'est pour définir sans ambiguïté des procédures effectives que Turing
a imaginé la machine de Turing. Dès lors que l'on possédait le modèle
théorique du calcul, la tentation de construire un automate capable
de l'incarner était inévitable, et c'est ce que fit von Neumann.
Le propos d'un programme informatique n'est pas de démontrer un
théorème à partir de certains axiomes et de certaines hypothèses, mais
d'effectuer un traitement qui à partir de certaines
données produira certains résultats. Pour se fixer les
idées on pourra prendre comme exemple de traitement la multiplication
de deux nombres selon la méthode apprise à l'école primaire, qui
constitue un algorithme parfaitement transposable tel quel en
programme informatique. Le traitement des données doit être
effectif, c'est-à-dire que la méthode de passage doit pouvoir
aboutir pratiquement au résultat. Le traitement comportera des étapes,
en nombre fini. Chaque étape consistera à élaborer à partir des
données initiales un état du calcul ; les états successifs du calcul
doivent conduire au résultat final ; pour progresser d'étape en étape
ces états successifs doivent être enregistrés : pour l'écolier armé de
son crayon, ce sera sur sa feuille de cahier ; pour l'ordinateur ce
sera dans sa mémoire. L'organe de l'ordinateur qui effectue les
calculs est nommé processeur ; chaque étape du traitement est
accomplie par une action du processeur ; une action du processeur
consiste à modifier, à affecter la mémoire, éventuellement
après avoir consulté son état précédent, pour y consigner le nouvel
état du calcul ; c'est très précisément ces opérations de consultation
et d'affectation de la mémoire que formalise la machine de Turing ; le
calcul sera terminé lorsque la mémoire sera dans un état qui contienne
le résultat recherché. À certaines étapes du calcul la procédure
effective doit comporter la possibilité de choisir entre deux
actions possibles en fonction des résultats intermédiaires --- par
exemple y a-t-il une retenue ou pas : la machine de Turing est dotée
de cette capacité. Ainsi on dit d'un automate capable de reproduire le
fonctionnement d'une machine de Turing quelconque qu'il possède
l'équivalence turingienne.
Nous avons introduit la notion de mémoire en notant qu'une
action du processeur consistait à consulter ou à modifier l'état de la
mémoire. Cette définition de l'action est très importante, elle trace
la ligne de séparation entre la conception mathématique traditionnelle
du calcul et la conception informatique liée à la notion de procédure
effective. La mathématique ignore cette notion d'état, qui
introduirait dans son univers d'abstraction un aspect physique
totalement incongru.
L'informatique, et plus précisément la programmation des
ordinateurs, confère au calcul une dimension concrète, effective.
C'est un peu comme si le papier sur lequel le mathématicien inscrit
les signes du calcul avec un crayon acquérait un statut théorique.
Ce passage permanent de l'abstrait au concret est d'ailleurs
l'agrément suprêmement fascinant de la programmation : dire c'est
faire. J'énonce la formule d'une action, et la machine l'exécute.
Les lignes qui précèdent n'ont d'autre but que d'évoquer pour le
lecteur ce qui apparente mathématiques et informatique, et ce qui les
distingue. La dimension effective de la programmation des ordinateurs
confère (impose) au calcul informatique une activité physique de
construction de la solution, enregistrée dans les circuits
électroniques de la mémoire de l'ordinateur (le mot anglais
storage, emmagasinage, suggère mieux la nature de son rôle). La
tâche du programmeur consiste donc à décrire les étapes successives de
cette construction, au moyen d'un langage de programmation.
Langages de programmation
Un processeur quelconque est caractérisé par le jeu des actions
élémentaires qu'il est capable d'effectuer. Ces actions élémentaires
sont appelées les primitives du processeur, ou, si le
processeur est une machine, les « instructions machine ». Un
programme pour un processeur de von Neumann est une suite de
primitives (d'instructions machine) du processeur destiné à
l'exécuter. Chacune de ces instructions élémentaires correspond à un
circuit logique du processeur considéré. L'ensemble des instructions
machine et des règles de leur rédaction constitue le langage
machine2.
Une idée capitale du modèle de von Neumann, c'est d'enregistrer le
texte du programme dans la mémoire de l'ordinateur, comme les données,
et de considérer en fait ce texte exactement comme s'il s'agissait de
données. Cette idée unificatrice permet d'appliquer aux programmes
les mêmes traitements qu'aux données, de considérer le contenu d'un
programme comme de l'information. Cela aura des conséquences évoquées
plus loin.
Les premiers programmes d'ordinateur étaient écrits en langage
machine, mais cela avait plusieurs
inconvénients. D'abord c'était extrêmement difficile et long, parce
que les instructions machine sont très élémentaires et très proches de
la structure interne du processeur, et induisent une formulation très
rigide et malcommode. Ensuite, chaque processeur a un langage machine
différent, et il faut donc réécrire le programme chaque fois que l'on
change d'ordinateur.
Pour pallier ces difficultés furent inventés les langages
évolués, dont le premier fut
Fortran créé par John Backus en 1954, suivi de Lisp et
Cobol, puis C, Ada, Java et bien d'autres. Un
langage évolué est un méta-langage par rapport au langage machine, un
programme en langage évolué doit être traduit en langage machine pour
pouvoir être exécuté par un ordinateur. Le programme qui effectue
cette traduction est généralement appelé
compilateur. Pour exécuter un programme donné écrit
en langage évolué sur plusieurs types d'ordinateurs, il suffit de
disposer pour chaque type d'ordinateur d'un compilateur de ce langage,
qui traduira le programme initial vers le bon langage machine. Un
langage évolué est donc inséparable de ses compilateurs.
Il peut y avoir plusieurs niveaux de langages évolués, un langage de
haut niveau étant traduit vers un langage de plus bas niveau, lequel
sera par exemple traduit en langage machine. Tout cela est un peu plus
compliqué dans la réalité, il faudrait parler du système
d'exploitation qui s'interpose entre le programme et l'ordinateur,
comme en fait un super-programme qui présente au programmeur une
vision plus abstraite de l'ordinateur, et aussi d'un langage tel que
Java qui est utilisé selon un schéma un peu différent, mais ces
nuances ne sont pas ce qui importe ici, encore une fois je renvoie
le lecteur qui en serait curieux à mon livre consacré à ce sujet, ou
à d'autres ouvrages d'excellents auteurs, notamment ceux d'Andrew
Tanenbaum[104, 106, 105].
Les erreurs de programmation
Les explications données ci-dessus nous permettent de préciser ce
que sont les erreurs de programmation, et en quoi elles se distinguent
des erreurs de calcul ou de logique qui peuvent affecter une démonstration
mathématique.
Le texte d'un programme informatique est constitué d'instructions qui
effectuent des actions, ou d'expressions dont l'évaluation se traduit
par des actions, selon le langage utilisé. Ces actions sont des
modifications de l'état de la mémoire. Un langage pratiquement
utilisable devra donc disposer d'un jeu de primitives suffisamment
riche pour exprimer les différentes actions souhaitables, et cette
richesse aura comme conséquence une grande complexité. L'initiation
à un langage de programmation demande à un étudiant motivé plusieurs
dizaines d'heures de cours et beaucoup plus encore d'exercices
pratiques, pour en posséder juste les rudiments.
Le premier type d'erreur que le programmeur peut commettre est
l'erreur de syntaxe, la violation des règles qui régissent le langage
utilisé. Une erreur de ce type est bénigne, parce que le plus souvent
le programme de traduction utilisé (le compilateur) la détectera et
donnera des explications qui aideront à sa correction. On suivra
pour l'éviter un conseil de Jacques Arsac :
ne jamais programmer sans avoir le manuel du langage sous la main.
Un second type d'erreur est de nature sémantique : le programmeur a
mal compris le manuel du langage, et il écrit un texte dont il pense
qu'il va donner le résultat voulu, alors qu'il va donner un autre
résultat, ou un programme faux, qui ne se termine pas, ou qui se
termine par une erreur explicite. Une des qualités d'un programmeur
expert, c'est de bien connaître la sémantique du langage qu'il
utilise, connaissance qui demande des années de pratique assidue.
Et il faut avoir le manuel du langage sous la main.
L'exécution d'un programme informatique peut aussi échouer
pour une raison qui n'est pas à proprement parler une erreur de
programmation, mais qui doit néanmoins retenir l'attention,
parce que ce type d'incident est très fréquent : ce sont les échecs
provoqués par le contexte technique. Ainsi, un programme qui écrit
des données sur disque peut échouer si le disque est plein. La
saturation de la mémoire est une autre cause d'échec courante.
En principe ces circonstances sont prévisibles par celui qui lance
le programme, mais pas par celui qui l'écrit.
Mais une fois vaincues ces erreurs techniques, restent les vraies
erreurs de programmation ; elles résultent d'une mauvaise
interprétation de l'énoncé du problème à résoudre, ou du choix d'un
algorithme inapproprié, ou d'une programmation fautive de
l'algorithme, c'est-à-dire que le programmeur aura écrit un texte qui
commande des actions qui ne conduisent pas au résultat voulu. On aura
compris de ce qui précède que l'élaboration d'un programme pour
résoudre un problème est une démarche de construction de la solution,
par induction. Il faut imaginer les actions à effectuer ; les méthodes
de preuve de programmes évoquées page
?? et sur lesquelles nous reviendrons à la section
3 page ?? ne pourront aider que dans certains
cas assez particuliers, parce qu'elles sont trop lourdes pour être
appliquées à l'ensemble d'un programme ; la plupart du temps il n'y a
rien qui puisse fournir au programmeur l'équivalent du caractère
auto-vérificateur du calcul mathématique, d'abord parce que la
programmation n'est généralement pas une démarche déductive, mais
aussi parce que le texte d'un programme est considérablement plus
volumineux que celui d'un calcul mathématique ordinaire : la taille
d'un petit programme vraiment utile pour un usage professionnel pourra
difficilement descendre en dessous de 10 000 lignes de texte, un
programme moyen aura plusieurs centaines de milliers de lignes, un
système d'exploitation général plusieurs millions, plusieurs
dizaines de millions si l'on y inclut les interfaces graphiques
interactives.
Il y a par contre des méthodes de programmation destinées à limiter le
risque d'erreur, qui feront l'objet de la section suivante. Le dernier
mot reste sur ce sujet à Peter J. Denning :
« il n y a pas de règles immuables à suivre pour écrire un programme
logique, efficace et lisible. Il y a bien sûr des guides, et certains
sont meilleurs que d'autres ; mais c'est le style du programmeur (ou
son absence de style), sa clairvoyance (ou non), sa créativité (ou son
absence) qui déterminent la qualité du produit final. »
Méthodes de programmation
L'invention et le perfectionnement des langages évolués allant de pair
avec la prise de conscience de l'importance du logiciel et de sa
difficulté, la question des langages de programmation, initialement
posée en fonction du processeur, fut de plus en plus posée en fonction
du programmeur. Pour écrire le plus vite possible des programmes
comportant le moins d'erreurs possible, il faut disposer de langages
adaptés. La linguistique de la programmation, c'est-à-dire la
recherche dans le domaine de la conception, de la réalisation et de
l'utilisation des langages de programmation, devint une des branches
principales de la science informatique. La puissance limitée des
premiers ordinateurs avait orienté cette recherche vers la conception
de langages faciles à traduire, donc à compiler, ce qui facilitait la
tâche de l'ordinateur. Dès les années 1960 la préoccupation
principale devint la facilité à écrire des programmes aussi corrects
et aussi lisibles que possible. L'évidence s'est en effet
imposée qu'un programme est lu beaucoup plus souvent par des êtres
humains, tels que son ou ses auteurs, ceux qui en assureront la
maintenance ou qui devront le modifier, que par un
compilateur. Les réalisations techniques marquantes
de ce courant de pensée furent les langages
Algol-60, Algol-68, PL/1,
Pascal et Ada, les chercheurs
les plus en vue, Edsger Dijkstra, C.A.R.
Hoare, Peter Naur,
Donald Knuth, Alan J. Perlis... La première qualité attendue d'un langage est, bien sûr,
l'équivalence turingienne, c'est-à-dire l'aptitude à exprimer sans ambiguïtés tout
algorithme formalisé par une machine de Turing, mais ces chercheurs
ont ajouté à cette exigence l'expressivité et la lisibilité.
L'expressivité doit être entendue à la fois comme la puissance
d'expression, la capacité à exprimer une opération complexe par un
formalisme aussi simple que possible, et comme la qualité de
l'expression, le fait que le texte du formalisme suggère facilement sa
signification au lecteur.
La linguistique de la programmation se préoccupe des aspects
morphologiques et syntaxiques des langages, mais aussi des problèmes
soulevés par la rédaction de textes assez longs, soit des méthodes de
construction de programmes, dont il sera question à la section suivante
de ce chapitre.
Méthodes de construction de programmes
Nous avons décrit ci-dessus le processus élémentaire de la
programmation, celui qui consiste à écrire les instructions ou les
expressions qui vont composer un programme. Un grand logiciel est
constitué de centaines de milliers ou de millions de lignes de texte,
le nombre de lignes étant souvent assez proche du nombre
d'instructions ou d'expressions élémentaires, auquel il convient
d'ajouter les lignes de commentaire qui sont du texte en langage
humain, destiné à faciliter la lecture du programme.
Écrire un programme d'un seul tenant qui compterait des centaines de
milliers de lignes serait très difficile, y retrouver et en corriger
les erreurs serait une entreprise pratiquement impossible. Aussi
a-t-on élaboré des méthodes pour découper de grands programmes en
unités plus petites, plus faciles à écrire et à mettre au point
séparément, puis réunies pour composer des ensembles plus importants,
un peu comme un livre est découpé en parties, chapitres et sections,
avec une table des matières et un index pour aider à s'y retrouver.
Ces unités de programme peuvent être appelées sous-programmes.
Le premier problème à résoudre pour permettre le découpage des
programmes en sous-programmes est d'organiser la circulation des
données entre les sous-programmes selon des règles qui respectent le
principe d'équivalence turingienne. Toujours dans l'idée de
rechercher clarté, lisibilité et expressivité, des pistes nouvelles
ont été explorées pour structurer l'information de façon à faciliter la
tâche des humains, qu'ils en soient rédacteurs ou lecteurs.
La programmation structurée
Le premier courant de pensée qui associa la recherche d'une syntaxe
claire et expressive à une organisation logique et commode des unités
de programme fut la programmation
structurée des années 1970, dont
les leaders Dijkstra, Niklaus
Wirth et Hoare
étaient issus du courant Algol. Cette école fut
représentée en France par Jacques Arsac et
Bertrand Meyer.
Pour réaliser un programme, il semble logique d'adopter une démarche
« de haut en bas » (top-down) : étant donné le problème à
résoudre, je le divise en sous-problèmes plus élémentaires et faciles,
que je divise eux-mêmes en sous-problèmes, jusqu'à ce que j'obtienne
une collection de problèmes simples, dont je programme les solutions
sous forme de sous-programmes qu'il ne me reste plus qu'à assembler.
On reconnaîtra ici l'influence du Discours de la Méthode de
René Descartes. Mais dans le cas de la construction d'un système
informatique cette règle est plus facile à énoncer qu'à appliquer,
parce qu'elle suppose connu le problème à résoudre, or c'est souvent
là que gît la principale difficulté. Aussi la démarche inverse, de bas
en haut (bottom-up), est-elle utilisée également : je réalise
des programmes qui modélisent un aspect partiel du problème, je
vérifie que le résultat est satisfaisant, ce faisant je découvre sans
doute des aspects du problème qui avaient échappé à la
spécification. En fait, programmer un problème aide à le comprendre,
et les approches de haut en bas et de bas en haut sont utiles toutes
les deux.
En réalité la principale difficulté de la programmation réside dans la
détermination de l'objet du programme à écrire. Paul
Graham[48] l'exprime ainsi : « En programmation, comme
dans beaucoup d'autres domaines, la difficulté n'est pas tant de
résoudre les problèmes que de choisir les problèmes à résoudre ». Une
approche fructueuse pourra consister à programmer des fonctions
générales, dont on sait qu'elles seront utiles de toute façon, sans se
préoccuper de l'objectif précis à atteindre. Une fois ces fonctions
disponibles, elles constitueront une bibliothèque de composants
destinés à résoudre toute une série de problèmes de bas niveau (accès
aux bases de données, affichage sur écran graphique, analyse des
messages introduits par les utilisateurs), qui faciliteront grandement
l'écriture de logiciels de plus haut niveau dont l'auteur aura
l'esprit libéré de ces questions et pourra ainsi mieux penser au
problème général. L'approche bottom-up revient en fait à
construire d'abord, au moyen d'un langage de programmation général, un
langage spécialisé doté d'opérations spécialement adaptées au problème
traité, puis à traiter le problème dans ce langage ad hoc ; les
langages de la famille Lisp -- Scheme sont particulièrement bien
adaptés à cette démarche, puisque l'on a pu écrire qu'il s'agissait de
langages de programmation programmables[36].
La programmation structurée fut l'aboutissement des premiers efforts
pour appliquer à l'activité de programmation une démarche
intellectuelle systématique, en garantissant certains aspects de la
cohérence formelle du programme et la permanence des propriétés de
cohérence et d'équivalence turingienne lorsqu'un programme est divisé
en sous-programmes. Les langages Pascal,
Ada et Modula furent conçus
selon les principes de la programmation structurée, avant de recevoir
des extensions destinées à les adapter au modèle de la programmation
par objets. Les principes de la programmation structurée peuvent être
considérés comme un acquis de la science de construction de
programmes.
La programmation par objets
Après la programmation structurée vint un autre courant significatif :
la programmation par objets, inventée
en Norvège à la fin des années 1960 par l'équipe de
Simula (Ole-Johan Dahl
et Kristen Nygaard), illustrée par les
langages Smalltalk (Alan Kay
à partir des années 1970), Eiffel (Bertrand
Meyer, années 1980) et C++
(Bjarne Stroustrup) pour finalement
connaître la consécration avec Java. Les langages
de la famille Lisp et Scheme
possèdent une approche objet qui leur est propre avec le modèle CLOS
(Common Lisp Object System). L'idée de la programmation par
objets consiste à « encapsuler » un ensemble de données liées entre
elles (par exemple, l'ensemble des données relatives à une même
personne dans une base de données) avec les sous-programmes destinés à
les traiter au sein d'une entité nommée objet3. Tous les objets relatifs à des personnes, pour
poursuivre avec cet exemple, appartiennent à la classe
Personne, qui constitue une sorte de modèle de ces objets
analogues, qui sont nommés des instances de la classe
Personne. Les sous-programmes associés aux objets sont
appelés des méthodes, et s'ils sont les mêmes pour tous les
objets de la classe ils figureront une seule fois pour toute la
classe. La notion de classe est une extension de la notion de
type4
que l'on trouve en programmation structurée. Une nouvelle classe peut
être obtenue par héritage d'une classe plus générale : ainsi, comme un
élève est un cas particulier de personne, je peux construire la classe
Élève à partir de la classe Personne, en héritant de
tous les attributs de Personne, tels que date et lieu
de naissance, adresse, etc. et en lui ajoutant des attributs
spécifiques propres à la situation d'élève : classe, première langue,
appartenance à l'association sportive ou au ciné-club, etc.
Cette façon de structurer et de hiérarchiser l'information permet de
mieux garantir la cohérence des données et des traitements, et ainsi
d'engendrer automatiquement des sous-programmes standard qui tirent
parti des règles de construction imposées aux objets. La hiérarchie
des traitements n'est pas réalisée par des appels de sous-programmes,
mais de la façon suivante : un objet envoie à un autre objet un
message qui lui demande d'exécuter telle ou telle de ses méthodes.
Pour la programmation structurée comme pour la programmation par
objets, le progrès dans la réalisation des programmes découle d'une
meilleure organisation de l'information, d'une réduction du désordre
(de l'entropie) dans les données et les sous-programmes. La première
méthode s'applique principalement à l'organisation de l'information
sur les traitements (le texte du programme), la seconde met l'accent
sur l'organisation des données : en fait les deux approches sont
complémentaires et la seconde a bénéficié des acquis de la première.
Pour apprécier les qualités et les défauts de tel ou tel langage de
programmation, il convient d'avoir conscience des objectifs poursuivis
par ses concepteurs, qui peuvent différer d'un langage à l'autre.
Ainsi des langages comme Perl ou
APL ont été conçus en visant la vitesse d'écriture
maximum : ils sont concis et laconiques, pleins d'abréviations qui
réduisent le nombre de caractères à écrire, mais cela donne un
texte à peu près illisible qui rend très aléatoire la recherche d'une
erreur dans un programme. À l'inverse, Ada a été
conçu d'après un cahier des charges (émis par le Department of
Defense américain, le DoD) qui mettait l'accent sur la réduction
des coûts de maintenance du logiciel : écrire un programme Ada
syntaxiquement correct est plus laborieux que de l'écrire en Perl,
mais une fois que la syntaxe est correcte, les erreurs à l'exécution
sont rares, et la structuration inhérente au langage facilite
modifications et corrections ultérieures.
Excès dans la pensée
Il y a eu beaucoup de verbiage autour de l'aptitude supposée du modèle
objet à « représenter naturellement le monde réel » : il faut beaucoup
de naïveté pour croire à une telle assertion, à supposer même qu'elle
ait un sens. Parmi ces fadaises, il a été beaucoup question d'un objet
véhicule, construit par composition d'un objet
carrosserie, d'un objet moteur et de quatre objets
roue. Il était ensuite loisible de disserter sur le point de
savoir si l'objet tracteur appartenait à la classe
Véhicule ou à la classe Matériel-Agricole. En fait,
l'objet informatique tracteur est une pure
abstraction destinée à résumer pour les besoins de
tel ou tel système d'information quelques
données que nous pouvons éventuellement posséder sur un tracteur réel,
piloté dans ses champs par un vrai paysan, ou en cours de fabrication
dans une usine, ou objet d'une procédure d'immatriculation, ou d'un
dossier de prêt bancaire. Cet objet tracteur sera selon nos
décisions arbitraires, sans doute liées aux objectifs visés par le
système d'information que nous construisons, une instance de la classe
Matériel-Agricole ou de la classe Véhicule, ou
encore de la classe Immobilisation, et le lien entre lui et
le tracteur réel est une pure convention. Dans tout cela il n'y a que
de l'information sur des choses, mais pas de choses du tout, et le
grand avantage de l'information par rapport aux choses, justement,
c'est qu'elle est abstraite, et que l'on peut en faire ce que l'on
veut sans autre effort que le dire ou l'écrire, c'est-à-dire sans
avoir à produire d'effet physique.
Où gît la difficulté de la programmation
La programmation et la construction de grands programmes ne sont pas
des disciplines faciles. Et il serait vain d'espérer maîtriser la
seconde sans avoir au préalable acquis la première. Les cursus de
Génie logiciel, destinés à l'acquisition de la seconde de ces
disciplines, voient affluer des étudiants qui n'ont jamais écrit une
ligne de programme de leur vie, mais qui voudraient bien, avec un
diplôme au titre ronflant et un petit costume anthracite, devenir
informaticiens en chef. Cette prétention est bien sûr ridicule, ce qui
ne l'empêchera peut-être pas d'être satisfaite d'ailleurs.
Il existe un champ de recherche relatif à la programmation par
l'utilisateur final ; il concerne les procédés qui permettent de
rendre la programmation accessible dans une certaine mesure à des
personnes dépourvues d'une véritable formation dans ce domaine. Les
résultats obtenus par ces chercheurs indiquent que ce qui est
difficile dans la programmation, ce n'est pas d'écrire une expression
ou une petite séquence d'instructions qui vont réaliser une opération
même assez complexe. La meilleure preuve en est la façon dont les
utilisateurs les plus variés arrivent à se servir d'un tableur : même
sans être programmeurs, beaucoup arrivent asez bien à programmer des
formules assez complexes dans les cases d'un feuille de calcul.
L'usage de logiciels statistiques ou de bases de données en montre
d'autres exemples.
Là où les choses deviennent plus difficiles, c'est lorsqu'il s'agit de
combiner plusieurs actions pour réaliser un programme plus vaste.
Organiser un texte assez long qui doit décrire des situations où il y
aura des choix à faire et des actions différentes selon les choix,
répéter des actions pour en appliquer l'effet à des données variées en
qualité et en quantité, c'est vraiment là que gît la difficulté ---
accompagnée en fait d'une autre difficulté tout aussi grande : la
maîtrise des entrées et sorties d'un programme. Découper un programme
en sous-programmes, organiser des données abondantes et variées d'une
façon adaptée aux traitements qu'elles auront à subir, constituent des
arts savants dont la maîtrise requiert un apprentissage théorique et
une expérience pratique. Les méthodes à objets accroissent la
puissance de ces procédés, mais pas forcément leur simplicité.
Un langage de programmation n'est pas seulement un moyen de demander à
l'ordinateur le résultat d'un calcul : rédiger le texte d'un programme
est aussi un moyen de noter et d'organiser ses idées, puis de les
partager avec d'autres personnes. Pour permettre la rédaction
harmonieuse de programmes éventuellement volumineux et complexes, un
langage doit être pourvu des mécanismes suivants :
-
des expressions primitives,
qui représentent les objets élémentaires du langage ;
- des moyens de composition, aussi nommés
constructions, qui
permettent de construire des expressions composées à partir
d'expressions plus simples ;
- des moyens d'abstraction pour nommer
des objets simples ou composés, y faire référence dans d'autres
parties du programme et effectuer sur eux des opérations logiques,
mathématiques ou autres. Nous donnerons à ces opérations sur les
objets du programme le nom de calcul, sans restreindre ce
terme à sa stricte acception mathématique.
Rôle de l'abstraction
Abstraction : Action d'abstraire, opération intellectuelle par
laquelle, dans un objet, on isole un caractère pour ne considérer
que ce caractère ; résultat de cette action.
(É. Littré, [
70])
Nous venons d'en parler, le processus d'abstraction, et le calcul sur
les entités abstraites qui en résultent, sont au coeur de la
problématique informatique. Programmer un problème du monde réel,
qu'il s'agisse de mécanique quantique ou de comptabilité, consiste
toujours à en identifier les éléments programmables pour ne plus
considérer qu'eux, dont on construira un modèle abstrait, objet du
programme. Il convient de s'interroger sur la nature et le statut de
l'abstraction.
L'abstraction, dont j'emprunte à Émile Littré la définition ci-dessus,
permet d'extraire d'un univers concret plus ou moins foisonnant des
modèles d'objet auxquels la pensée pourra plus facilement s'appliquer,
et par là elle est au coeur de la démarche scientifique. Elle
permet aussi de créer des classes ou des catégories d'objets. Ainsi au
sein de la classe5 des arbres je peux ne m'intéresser qu'à
certaines caractéristiques, notamment celles du feuillage, et créer
les sous-classes « conifères » et « feuillus ». Si mes définitions
sont bien construites, je pourrai formuler des énoncés relatifs aux
conifères en général, et ces énoncés pourront s'appliquer aux pins,
aux sapins, aux épicéas, etc.
Chacun de nous fabrique des abstractions tous les jours, ne serait-ce
que pour classer les personnes qu'il rencontre. Mais cette activité
instinctive, naturelle, nous est masquée par notre éducation qui nous
transmet de l'abstrait (les théories mises au point par des
« génies ») et qui nous détourne de la pratique (explicite et lucide)
de l'abstraction. D'autre part, le raisonnement abstrait systématique
est une élaboration culturelle, transmise par l'éducation, et selon sa
formation et ses aptitudes chaque individu possédera un entraînement
plus ou moins grand à ce type de raisonnement. La programmation des
ordinateurs exige un niveau d'accoutumance au raisonnement abstrait
plutôt élevé, tel que peuvent en posséder des personnes ayant reçu une
formation scientifique, et c'est ce qui fait que de telles personnes
pourront éprouver moins de difficulté pour aborder cette activité,
même si leur stock de connaissances ne leur confère pas un avantage
décisif.
Les études scientifiques peuvent conférer à ceux qui en ont bénéficié
une autre tournure d'esprit favorable : l'habitude de considérer le
savoir et les connaissances comme des éléments de communication et
d'échange, par opposition à la tradition artisanale encore très
présente dans les métiers, pour laquelle les savoir-faire sont des
secrets de fabrique. Edsger Dijkstra a
rapproché dans un article célèbre cette situation de la création, à
partir du XIIe siècle, des universités, qui dispensaient
publiquement des savoirs qui auparavant étaient la propriété privée et
secrète d'entrepreneurs de la science. Parmi les méthodes de
construction de programmes que nous évoquerons, celles qui donnent les
meilleurs résultats reposent notamment sur des échanges intenses de
connaissances, et les développeurs qui ne seraient pas enclins à
ceux-ci auraient du mal à s'adapter à celles-là.
Hormis cet entraînement très général au raisonnement abstrait, qui
peut être acquis au cours d'études scientifiques, mais aussi tout
autrement, par la pratique du dessin industriel ou de la linguistique, par exemple, rien dans les cursus
secondaires français actuels ne prépare réellement à l'acquisition des
bases de la programmation, et il n'y a donc aucune raison de
restreindre l'accès des premiers cycles à orientation informatique aux
titulaires de baccalauréats scientifiques.
Si la France avait voulu prendre au sérieux l'informatique et la
formation des informaticiens, elle aurait suivi les recommandations
formulées par Jacques Arsac il y a au moins
vingt-cinq ans en créant un CAPES et une agrégation d'informatique (ce
sont les diplômes qui permettent d'enseigner dans les établissements
secondaires). Il faudrait apprendre à programmer tout comme on
apprend à parler l'anglais : parce que c'est utile, parce que sans
cela il y a beaucoup de choses que l'on ne peut ni comprendre, ni
faire. Au lieu de cela on a préféré saupoudrer les cursus de quelques
cours de sensibilisation clinquants et démagogiques.
3 Les illusions de la spécification
Les sections précédentes ont évoqué les inventions des langages évolués,
de la programmation structurée et de la programmation par objets, qui
toutes ont représenté des progrès dans l'art de la programmation en
améliorant la productivité des programmeurs, la justesse des programmes
et la facilité à les modifier et à les corriger en cas d'erreur.
Ces améliorations concernent l'activité des programmeurs : il n'en
reste pas moins que la programmation, même facilitée par des langages
bien conçus et des méthodes simplificatrices, reste une activité
hautement complexe, qui demande de grandes capacités d'abstraction et
beaucoup de temps pour un résultat finalement assez incertain.
Un modèle de division du travail
Nous avons écrit plus haut que la détermination de l'objet du
programme à écrire était la principale difficulté de la programmation,
et nous ajoutons ici que cette détermination doit être écrite dans le
programme même, c'est d'ailleurs pour cela que c'est si difficile.
Un aphorisme du folklore informatique en donne une idée : « Avec les
ordinateurs, ce qui est ennuyeux, c'est qu'ils font ce qu'on leur
demande, pas ce qu'on aurait voulu. »
Le coût économique de cette difficulté a logiquement engendré la
recherche de moyens de la contourner. Que la difficulté intellectuelle
réside dans la programmation, perçue comme l'étape de fabrication du
produit final, était difficile à comprendre pour des managers habitués
au processus industriel. Dans l'industrie mécanique, la difficulté
intellectuelle réside au bureau d'études, où des ingénieurs hautement
qualifiés conçoivent les objets à réaliser. Une fois la conception
terminée, ils disposent d'un excellent outil pour transmettre les
consignes de réalisation aux ouvriers : c'est le dessin
industriel, ou le programme de machine à
commande numérique qui lui a généralement succédé. Comme nous l'avons
vu au chapitre précédent, nous pouvons dire que le système industriel
taylorien organise la séparation stricte de la conception et de la
fabrication. La conception effectuée par les ingénieurs se concrétise
dans des dessins (ou aujourd'hui des programmes de machines à commande
numérique) qui permettent aux régleurs des ateliers de paramétrer les
machines de telle sorte que les opérateurs (c'est ainsi qu'aujourd'hui
on nomme les ouvriers spécialisés) puissent fabriquer les pièces sans
aucune marge de manoeuvre. La transmission des consignes est sans
ambiguïté aucune (du moins en théorie).
Essais de division du travail en informatique
Les managers qui ont cherché à organiser le travail informatique se
sont tous plus ou moins inspirés de ce modèle industriel : ils ont
cherché à inventer le procédé qui serait à la programmation ce que le
dessin industriel ou la CAO sont à la
fraiseuse, à l'étau-limeur ou à la machine à commande numérique.
Le degré zéro de l'informatique taylorienne
Dans les années 1960-1970 la division du travail était entre les
programmeurs qui écrivaient des programmes d'un côté, et de l'autre
les analystes qui produisaient des organigrammes, c'est-à-dire des
schémas censés représenter l'enchaînement des opérations élémentaires
du programme, que les programmeurs n'auraient plus qu'à « coder ».
L'emploi dans ce contexte des termes coder, codage et codeur vise à
dévaloriser l'acte de programmer, à suggérer qu'il n'est qu'une
opération mécanique dont l'intelligence serait toute contenue dans
l'organigramme produit par les analystes du service études, et que les
programmeurs du service production n'auraient qu'une tâche mécanique
de transposition à accomplir. D'ailleurs, pour joindre l'acte à la
parole et donner à cette façon de voir une valeur autoréalisatrice, on
s'empressa de recruter des programmeurs sous-qualifiés et de les
entasser dans des ateliers taylorisés. Le résultat fut les millions de
lignes de Cobol au style dit « en plat de spaghettis » qui encore
aujourd'hui assurent une bonne partie de la gestion des banques et des
compagnies d'assurance.
J'ai eu l'occasion de collaborer avec un collègue qui travaillait dans
un tel contexte au début des années 1980, au sein d'un établissement
financier. Il me cita l'exemple du programme qui créait le fichier
quotidien des compensations inter-bancaires, destiné à permettre à
l'établissement de se faire payer les chèques tirés sur d'autres
banques qu'il avait reçus en paiement de ses clients. Le montant
quotidien de l'opération se chiffrait en millions de francs. Au moins
une fois par semaine le programme échouait, ce qui obligeait à
financer le retard de paiement au prix de l'argent au jour le jour.
Autant dire que le coût du dysfonctionnement était colossal,
équivalent au salaire de dizaines de programmeurs. Mais corriger
l'erreur était proprement impossible, parce qu'elle était enfouie dans
un programme monolithique énorme dont le texte source en Cobol était
perdu depuis longtemps et dont l'organigramme disponible correspondait
à une version périmée ; en outre le programmeur qui en était l'auteur
et qui aurait peut-être pu intervenir avait quitté la société. Toute
intervention aurait pu déclencher une catastrophe encore plus grave.
Cette anecdote, loin d'être exceptionnelle, reflétait la situation
standard de l'informatique de gestion jusqu'aux années 1990, et il
s'en faut de beaucoup que ce cas appartienne au passé.
Il faut ajouter que l'outil prétendu de conception, l'organigramme,
était particulièrement indigent. Il consistait à aligner des
rectangles et des losanges censés représenter les actions successives
du programme et ses embranchements, c'est-à-dire qu'au mieux il était
redondant par rapport au texte du programme, et la plupart du temps il
était faux. Trop détaillé pour donner une vision d'ensemble, il ne
l'était pas assez pour permettre une transcription automatique en
texte de programme.
Première solution palliative : externaliser
L'ampleur des dégâts provoqués par cette organisation du travail
fut telle que chacun chercha des palliatifs. Les entreprises qui
avaient tenté d'assurer elles-mêmes maîtrise d'ouvrage et maîtrise d'oeuvre se
trouvaient à la tête de logiciels inadaptés, difficiles
à maintenir et bientôt périmés, ainsi que d'effectifs importants
de personnels à la qualification et au potentiel d'évolution
incertains. Les ingénieurs commerciaux des sociétés de prestations
de service n'eurent guère de difficulté à les convaincre que ce
n'était pas la méthode qui était mauvaise, mais le fait même
d'entreprendre soi-même le travail d'informatisation, et qu'il
serait bien plus judicieux de confier cette mission à des entreprises
spécialisées.
La légende a longtemps couru, et court encore, en France, que la
France posséderait une puissante industrie du logiciel. Cette illusion est produite par le chiffre d'affaires
important des Sociétés de Services et d'Ingénierie Informatiques
(SSII), interprété par des statisticiens et des économistes peu
informés des réalités de l'informatique comme celui d'une illusoire
industrie du logiciel. En réalité l'activité réelle de beaucoup de ces
SSII est assez peu différente de celle des agences de personnel
intérimaire, à tel point que certaines ont dû
affronter les tribunaux pour éviter de justesse la qualification de
leur activité en service d'intérim, ce qui aurait entraîné des
conséquences lourdes et défavorables en matière de droit du travail et
de fiscalité. Ces SSII, loin de créer de la plus-value en mettant des
logiciels nouveaux sur le marché, vendent essentiellement du service.
L'analyse de leur chiffre d'affaires, certes exceptionnellement élevé
si on le compare aux valeurs observées dans les autres pays de l'OCDE,
révèle une clientèle particulièrement abondante et assidue dans le
secteur de l'administration publique, qui a accueilli avec un
enthousiasme particulier l'idée de se débarrasser de toute compétence
informatique. Cet objectif « incompétence totale » est d'ailleurs
aujourd'hui pratiquement atteint, puisque dans les DSI la plupart des
personnes formées à l'informatique deviennent des gestionnaires de
contrats et ne maîtrisent plus du tout les techniques utilisées par les
fournisseurs --- lesquels sont d'autant plus à l'aise pour dicter leur
loi ; si ces personnes dotées de compétences refusent le « projet
professionnel » qui leur est ainsi proposé, elles sont repoussées vers
la périphérie du dispositif.
Plusieurs facteurs concourent à cet enthousiasme dans l'éradication de
la compétence interne des entreprises. Traditionnellement, les milieux
dirigeants de l'administration française considèrent la compétence
technique comme un attribut indigne d'eux, bon pour des tâcherons. En
être dépourvu est une condition nécessaire pour accéder aux plus
hautes responsabilités. Le lecteur pourra trouver des portraits pris
sur le vif de tels dirigeants sur le site de Michel Volle, comme par exemple
ici[121, 117]. Comme les dirigeants des
plus grandes entreprises françaises se recrutent dans la haute
administration (issus de l'ENA : Conseil d'Etat, Inspection des
Finances, Cour des Comptes etc. ; issus de l'X : Corps des Mines, des
Ponts-et-Chaussées, etc.) cette culture de l'incompétence irrigue
également celles-ci. Dans ce contexte, dire à des dirigeants qu'ils
n'ont pas besoin d'être compétents, ni de posséder trop de compétence
dans leur entreprise, en tout cas pas parmi leurs cadres dirigeants,
ne peut que les conforter dans leur penchant traditionnel.
Il faut dire pour être équitable que les informaticiens ont aussi
souvent abusé de leur pouvoir, qui devenait considérable, et qu'ils ont
contribué eux-mêmes de façon importante à scier la branche sur
laquelle ils étaient assis. Pour une entreprise, détenir des compétences
n'est pas une fin en soi ; ceux qui les détiennent doivent les faire
évoluer pour tenir compte des innovations techniques autant que des
évolutions de l'entreprise ; la présence d'une population importante
d'informaticiens qui ne voulaient pas ou ne pouvaient pas s'adapter
aux nouvelles orientations a souvent été une charge insupportable
pour leurs employeurs, et cette expérience n'a pas peu contribué à
leur pulsion d'externalisation. Nous reviendrons sur cet aspect de
la question informatique à la page ??.
À cette situation générale vient s'ajouter vis-à-vis de l'informatique
ce qu'il faut bien appeler une haine particulière. Mon collègue
Norbert Paquel, statisticien, économiste,
spécialiste des systèmes d'information et observateur fin et exercé de
l'économie française, m'a expliqué un jour que, pour que
l'informatique marche bien dans ce pays, il aurait fallu que dès le
début des années 1950 soit créée une école d'application de l'École
Polytechnique dédiée à l'informatique, qui aurait alimenté un corps
d'informaticiens de l'État, civils ou militaires. Ce corps aurait
développé ses solidarités, ses implantations, ses terrains de chasse
gardée et ses filières, avec ses voies traditionnelles de pantouflage,
bref, l'informatique serait devenu un élément normal du système
militaro-industriel français, à l'image de l'Armement, des
Télécommunications ou des Ponts et Chaussées. Faute d'avoir suivi ce
parcours, l'informatique n'a jamais atteint en France une
respectabilité considérable, et, comme par ailleurs elle se
développait et procurait aux marginaux qui choisissaient d'y faire
carrière d'assez belles situations et des promotions rapides, ces
succès perçus comme illégitimes engendraient envie, rancoeur et
animosité dans les rangs des corporations qui se considéraient
elles-mêmes comme plus respectables et plus méritantes.
J'ai eu l'occasion d'observer maintes manifestations de cette
détestation de l'informatique, sous des formes très diverses, une des
plus curieuses étant l'annonce de la « fin de l'informatique », ou sa
variante, la fin des salaires élevés pour les informaticiens. Dans la
bouche de dirigeants, de telles prophéties peuvent prendre une valeur
auto-réalisatrice, et effectivement, de façon récurrente,
administrations et grandes entreprises, saisies par une mode
panurgique, liquident leurs équipes d'informaticiens et externalisent
à tout va, en proclamant haut et fort que c'est la voie de la
modernité. Tout aussi régulièrement, à l'issue d'un délai que
j'estime en moyenne à quatre ou cinq ans, les mêmes sont amenés à
constater les résultats catastrophiques de cette politique, et, sans
tambours ni trompettes, essaient de reconstituer ce qui peut l'être.
Bien sûr, dans le climat social actuel, entre-temps les équipes
dirigeantes ont été renouvelées au moins deux fois, ce qui dispense de
toute réflexion auto-critique et de toute analyse approfondie.
Il existe une forme pseudo-savante de détestation de l'informatique :
la proclamation hors contexte du paradoxe de
Solow, du nom de son auteur l'économiste
américain Robert Solow, qui a dit en 1982
« You can see the computer age everywhere but in the productivity
statistics. » (« on voit la révolution informatique partout, sauf
dans les statistiques de productivité » ; la référence écrite est dans
la New York Review of Books, 12 juillet 1987). Au début des
années 1980 régnait l'informatique centralisée, assez mal maîtrisée
par les entreprises ; en d'autres termes les innovations apportées par
l'informatique n'avaient pas encore été assimilées, et de ce fait
elles n'avaient pas encore porté leurs fruits. Depuis les choses ont
malgré tout changé, et d'ailleurs Robert Solow a publiquement modifié
son diagnostic. Mais chez les cuistres ignorants, son ancien
apophtegme voisine avec le détestable truisme sur les chercheurs qui
cherchent et ceux qui trouvent. On consultera avec profit, à ce sujet,
un article que Michel Volle a consacré à
l'économie du système d'information[110], ainsi qu'un
texte de Claude Rochet[93]
assorti de nombreuses références accessibles en ligne.
Le débat sur le paradoxe de Solow s'est déplacé vers la question de
l'inégale aptitude des économies américaine et européenne à tirer
profit des innovations informatiques, mais l'opportunité d'y avoir
recours n'est plus une question depuis longtemps : sans
l'informatique, l'Airbus ne peut ni être conçu, ni être construit, ni
voler, ni être vendu ; les banques devraient recruter des millions
d'employés si elles voulaient se passer d'ordinateurs, ainsi
d'ailleurs que les administrations fiscales qui ont pu grâce à
l'automatisation multiplier par plus de 10 le nombre de contribuables.
Pour en revenir à la question de l'utilité des compétences en
informatique au sein de l'entreprise, il ne faudrait pas que le
lecteur retire des lignes qui précèdent l'idée qu'il faille rejeter
toute idée d'externalisation, bien au contraire. Il existe tout
d'abord une forme d'externalisation qui est presque toujours hautement
recommandable lorsqu'elle est possible et pratiquée raisonnablement,
c'est le recours à des logiciels ou à des systèmes qui existent déjà,
comme les progiciels : nous aurons l'occasion d'y
revenir au chapitre 6. Il y a aussi des activités
qu'une entreprise moderne aura tout intérêt à confier à des
spécialistes extérieurs. Mais pour qu'une externalisation soit un
succès, il faut avoir une idée la plus précise possible de ce que l'on
veut externaliser. Il vaut mieux aussi que ce ne soit pas un élément
trop stratégique du dispositif de l'entreprise, parce qu'il y aurait
alors un risque de perdre le contrôle d'un élément clé. Il est
souvent facile d'externaliser des choses dont la définition est assez
simple, parce que très circonscrite : le nettoyage des locaux, la mise
sous enveloppe et l'expédition d'envois en volume, l'entretien d'un
parc automobile. Ce peut être aussi une intervention technique
ponctuelle très spécialisée au sein d'une équipe qui ne possède pas
cette compétence précise. Mais l'externalisation du système
d'information, ou même simplement de ses
composantes techniques, ne répond visiblement pas à ces critères. Les
externalisations réussies concernent pour la plupart des activités qui
ne demandent aucune compétence particulière ; dès lors qu'un travail
révèle une complexité, l'intérêt pour une entreprise (publique ou
privée) est de le capitaliser, donc de se l'approprier
(knowledge management, veille, etc.)
Régie ou forfait : à bon chat, bon rat
Lorsqu'une entreprise confie un projet
informatique à une société de services, situation déjà évoquée à la
page ??, il y a deux types de solutions
pour l'organisation du travail et de sa facturation :
-
au forfait, le prestataire s'engage, sur la base d'un cahier des
charges détaillé, à réaliser le système demandé dans un délai donné
pour une somme fixée une fois pour toutes au départ, à lui de mettre
en place les moyens appropriés pour mener le projet à bien ; il a
une obligation de résultat ;
- en régie, le prestataire a plutôt une obligation de moyens, il
met à la disposition du client un certain nombre d'ingénieurs et de
programmeurs sous la conduite d'un chef de projet, et la facturation
a lieu à la journée, en quelque sorte comme pour un taxi, et le
travail est fini quand il est fini ; c'est en fait de la délégation
de personnel plus ou moins déguisée.
Les contrats au forfait ou en régie sont à la mode alternativement ;
l'administration française s'interdit les contrats en régie ; en fait
l'un comme l'autre système peuvent réussir ou échouer.
Si le contrat est au forfait et que le client ne dispose pas des
compétences et des effectifs suffisants pour participer activement au
projet, le prestataire peut être tenté d'interpréter de façon très
restrictive le cahier des charges et ses propres obligations aux
termes du contrat, et au contraire de manière extensive et
pointilleuse les obligations du client, en termes de disponibilité des
interlocuteurs, de fourniture de documents et de dates pour
l'exécution de ces obligations. Si les équipes du client participent
activement au travail et que l'estime réciproque règne entre les
participants, ce type de dérive est moins probable et de toute façon
plus limité, parce que chacun est en mesure d'apprécier le travail à
faire et son volume. Mais, dans un contexte où chaque entreprise
lutte pour sa survie et où, pour une société de services, avoir des
employés en attente de travail (en « inter-contrat ») est une lourde
charge, si le prestataire a pu mesurer l'incompétence de son client,
il résistera difficilement à la tentation de gonfler les facturations
en exigeant la signature d'avenants au contrat initial pour toute
prestation supposée à tort ou à raison ne pas avoir été prévue par le
cahier des charges.
Un responsable d'une société de services m'a déclaré franchement que
les services publics jouaient fréquemment ce rôle du client incompétent,
et que la facturation de services aux administrations n'avait rien à
voir avec les tarifs pratiqués pour les entreprises privées. La
surfacturation systématique aux dépens des administrations incapables
de s'en apercevoir est considérée comme une juste compensation pour des
charges sociales exorbitantes et un droit du travail trop rigide.
Si le travail au forfait comporte des inconvénients, le travail en
régie n'en est pas exempt. On peut même dire qu'il est pratiquement
incontrôlable si le client ne dispose pas de sa propre équipe et d'un
chef de projet capable de suivre le travail au jour le jour. Il est
tellement confortable d'avoir une réserve permanente de personnels en
régie, un peu sous-occupés mais de ce fait assez disponibles en cas
d'urgence, et d'emploi plus malléable que les personnels internes !
Cette pratique est à la limite de l'emploi intérimaire, et les clients
doivent veiller soigneusement à éviter que les personnels du prestataire
ne se retrouvent dans la situation de demander la requalification de
leur contrat de travail à leurs dépens.
Pour conclure sur ces aspects de la sous-traitance, il semble
raisonnable de dire qu'une sous-traitance modérée peut être un
excellent moyen de renforcer le potentiel de l'entreprise, à condition
que cette externalisation soit équilibrée par le maintien d'une
véritable équipe du client, capable de conserver la compétence interne
et de contrôler les prestataires, et pas juste de rédiger des cahiers
des charges. L'externalisation à tout crin assortie de la liquidation
des compétences internes est une erreur, et celui qui la commet ne
tarde pas à être puni par la déliquescence de son système
d'information, l'explosion de ses coûts, l'incohérence de ses
procédures de gestion, bref par la perte du contrôle d'éléments
fondamentaux du fonctionnement de l'entreprise.
L'externalisation peut être un succès si elle est menée par une
entreprise compétente qui sait ce qu'elle fait ; elle saura alors
choisir de bons prestataires et obtenir d'eux un travail de qualité :
à bon chat, bon rat.
L'informatique est pilotée par l'offre
L'informatique est pilotée par l'offre : cette assertion peut sembler
immorale, scandaleuse, mais elle est vraie.
Dans le monde idéal dont pourraient rêver les utilisateurs, c'est la
demande qui devrait piloter les projets : les maîtres d'ouvrage
recueilleraient auprès des stratèges et des responsables fonctionnels
l'expression des besoins, qu'ils mettraient sous la forme de cahiers
des charges, au vu desquels architectes et maîtres d'oeuvre
élaboreraient des solutions adaptées. Bref, c'est un refrain que nous
avons déjà souvent évoqué et que nous entendrons encore.
Eh bien cela ne se passe pas ainsi. Les stratèges et les responsables
fonctionnels n'ont cure d'exprimer leurs besoins sous une forme
suffisamment élaborée et raisonnable pour être utilisable, et les
cahiers de charges qui résultent de l'écoute de leurs frustrations, si
ce n'est de leurs caprices, sont lourds de catastrophes à venir.
L'informaticien face au donneur d'ordres doit adopter l'attitude du
médecin face à son patient : les propos de celui-ci sont des
symptômes, mais ce n'est pas le malade qui établit le diagnostic ni
qui rédige l'ordonnance. Formuler un besoin, c'est dans notre cas
rédiger un cahier des charges, dont nous avons dit qu'il serait
éminemment modifiable et évolutif. Faire ce travail de rédaction,
c'est un métier, le métier d'informaticien, qui rédige en pleine
conscience des possibilités techniques, même s'il s'interdit
d'effectuer des choix techniques prématurés ou arbitraires.
En fait, c'est l'offre de solutions disponibles qui détermine le
caractère raisonnable des besoins, simplement parce que l'évolution
technique dans le domaine informatique est très rapide, alors que les
structures et l'organisation des entreprises évoluent plus lentement.
Il n'est donc pas aberrant de saisir l'occasion de techniques qui
arrivent à maturité pour les appliquer à des problèmes que l'on aura
mis en évidence justement pour cette occasion.
Cela semble mettre les choses sens dessus-dessous, mais l'observation
de cas réels confirme que ce type d'opportunisme donne de meilleurs
résultats que le volontarisme qui ferait fi des contraintes techniques.
Quant à confier tous les pouvoirs à l'utilisateur final, c'est le
moyen le plus sûr d'aller à l'échec en passant par l'explosion budgétaire.
Après l'échec...
Lorsque la taylorisation et l'externalisation aveugles ont échoué il
faut chercher autre chose. Les entreprises les mieux dirigées savent
que la solution réside généralement dans un savant équilibre entre le
maintien d'une compétence et d'un potentiel de développement internes
complétés par une sous-traitance introduite en doses bien calculées et
aux bons endroits. Mais un tel équilibre ne peut être que provisoire :
comme nous l'avons exposé dans l'exemple de la section
4, il viendra forcément un jour où les départements
administratifs de l'entreprise auront la peau de l'informatique
interne, si elle n'est pas liquidée à l'occasion d'une restructuration
ou sur la foi des promesses d'une société de services désireuse de
s'implanter. Et les sociétés de service ne sont-elles pas incitées par
la logique de leur démarche commerciale à toujours proposer le
renouvellement de l'informatique de leurs clients, même si l'utilité
de ces innovations est douteuse ? Il serait d'ailleurs vain de
prétendre que l'informatique interne n'a aucune part de responsabilité
dans son destin, et un prochain chapitre nous montrera pourquoi et
comment il est effectivement difficile à l'entreprise d'obtenir de ses
informaticiens ce qu'elle est en droit d'en attendre. En tout état de
cause, selon la presse professionnelle[87], en
cette année 2004, l'espérance de vie professionnelle d'un directeur du
système d'information dans une entreprise française privée ou même
publique est de l'ordre de vingt mois, ce qui donne la certitude
qu'aucun projet cohérent de quelque ampleur ne peut être mené à bien.
- 1
- Dans les lignes qui précèdent le mot
calcul était utilisé selon l'acception mathématique de ce terme. À
partir d'ici nous l'emploierons au sens informatique plus large de
manipulation symbolique composée d'opérations de traduction et
de réécriture, bref, de traitement de données.
- 2
- Le
lecteur désireux d'en savoir plus sur l'histoire et la morphologie
technique des processeurs et des langages pourra se reporter par
exemple à mon livre consacré aux ordinateurs et aux systèmes
d'exploitation[11].
- 3
- Le mot
« objet » est un faux ami dangereux, puisque dans le langage courant
il désigne un être du monde réel, alors que dans le langage
informatique il désigne une représentation résultant d'une
abstraction.
- 4
- Le lecteur non spécialiste qui aurait quelques souvenirs
de son programme de mathématiques de classe terminale peut voir le
type comme une structure algébrique, telle que l'anneau des entiers
relatifs ou le corps des réels. Un type est un nom donné à
la collection des valeurs que peuvent prendre certaines entités, il est
défini par les éléments suivants :
-
Un ensemble de définition, appelé domaine du type. Les
éléments du domaine sont les valeurs possibles du type (les
nombres entiers, ou les chaînes de caractères...).
- Les opérations définies sur les éléments du type
(l'addition, la multiplication et la comparaison pour des
nombres, la concaténation et la comparaison pour des chaînes
de caractères, par exemple).
- 5
- Le mot classe n'est pas employé ici dans
son acception botanique.
© copyright Éditions Vuibert & Laurent Bloch 2004, 2005
Page d'accueil de ce livre