Entretien avec Laurent Bloch
8 décembre 2001
Nota Bene de Michel Volle
: J'ai eu avec Laurent Bloch (INSERM) le 31 octobre 2001 un entretien sur les langages
de programmation. Je l'ai jugé assez intéressant pour retranscrire mes notes et les
faire valider par l'auteur. Bjarne
Stroustrup a écrit : "Les comparaisons entre langages sont rarement
intéressantes et encore plus rarement équitables (...) Les auteurs s'efforcent
à l'impartialité, mais leurs avis sont inévitablement faussés parce qu'ils
adhèrent à une application, un style de programmation, une
culture du programmeur" (1). Il y a du vrai dans cette remarque : chaque
programmeur s'attache au langage qu'il connaît parce qu'il sait l'utiliser sans
effort ; certains sont d'un "patriotisme" aussi sectaire que celui des
supporters d'une équipe de football. Pourtant à chaque langage correspond une
aire d'utilisation où il sera le plus efficace, et en dehors de laquelle il vaut
mieux en utiliser un autre. La remarque de Stroustrup s'applique aux créateurs
de langages, car chacun aime son propre enfant, et aussi aux techniciens
dépourvus de curiosité. Laurent Bloch n'est pas de ceux-là ; s'il exprime une
préférence décidée pour Scheme (prononcer Skim), c'est après comparaison
avec d'autres langages
qu'il maîtrise également. Je lui laisse la parole :
- Je m'intéresse aux langages informatiques. Il faut être
polyglotte en la matière et savoir utiliser chaque langage dans le domaine
auquel il convient le mieux. Pour ma part, j'ai programmé jadis en PL1
et en assembleur, naguère en Pascal, aujourd'hui je programme en Scheme et un peu
en C, voire en C++. Mon langage de prédilection est Scheme (dialecte de LISP)
pour des raisons que je vais expliquer.
L'évolution des langages
L'évolution des langages a été marquée par le conflit de deux
objectifs contradictoires : l'efficacité d'une part, l'abstraction et l'expressivité de
l'autre. Voici le sens de ces trois termes :
- - "Efficacité" veut dire rapidité
de traitement lors de l'exécution du programme ;
- - "Abstraction" : les couches physiques
de l'exécution du programme sont masquées au programmeur ;
- - "Expressivité" : le programme est écrit dans
une langue compréhensible pour un être humain, qui permet de
transcrire les concepts du métier de l'utilisateur.
L'évolution s'est faite au détriment de l'efficacité
et au bénéfice de
l'expressivité. Ceci s'explique : d'une part la croissance des
vitesses et capacités fournies par les matériels, ainsi que l'amélioration
des techniques de compilation, rendent moins nécessaire
la recherche de la haute performance ; d'autre part la
complication des programmes les a rendus plus difficiles à maîtriser
intellectuellement. On ne recherche l'efficacité que pour les calculs
scientifiques utilisant les éléments finis, ou pour la production d'images : ils demandent de gros volumes de calculs répétitifs. Les militaires,
pour leur part, recherchent avant tout non l'efficacité comme on le
dit parfois, mais la sûreté de fonctionnement : lorsqu'on lance un
missile, il importe qu'il ne se trompe pas de cible. Les militaires
préfèreront toujours une solution éprouvée, même si elle est
inefficace ou un peu désuète.
La victoire des techniciens sur les
intellectuels
Cette tendance historique, que l'on peut qualifier de « moderne », a été
toutefois contrariée par des évolutions de sens contraire dont il
faut comprendre les racines sociologiques. Le langage C n'est rien
d'autre qu'un assembleur plus puissant : c'est un langage "de bas niveau", car il ne masque pas au programmeur les éléments techniques du
fonctionnement du programme. C'est donc un langage pour techniciens. Il
convient pour programmer un pilote d'imprimante ou un lecteur de
disque, ou encore un système d'exploitation, mais il serait catastrophique pour
programmer un logiciel
comptable : selon toute vraisemblance, l'auteur du logiciel comptable ne
le maîtrisera pas
vraiment.
Le triomphe de C dans le monde
de la programmation a marqué la victoire des techniciens sur les
intellectuels au sein de l'informatique. Les intellectuels avaient tenté
d'une part de faire de l'informatique une discipline scientifique
reconnue par les autres disciplines, d'autre part de faire prévaloir
les exigences intellectuelles (clarté, maîtrise conceptuelle, rigueur,
élégance etc.) à l'intérieur de l'informatique. Ils se sont heurtés aux
techniciens qui se soucient peu d'élégance ou de clarté et qui aiment
bien au contraire être protégés professionnellement par la complexité
de procédures qu'eux seuls maîtrisent, et par un jargon pour initiés
qu'eux seuls comprennent. Ainsi les techniciens haïssent Pascal, dont la clarté les gêne et qu'ils
estiment trop facile à apprendre pour un non-initié (ils disent que Pascal est «
bon pour les
gonzesses »).
Les leaders intellectuels de l'informatique ont
par ailleurs échoué à introduire leur discipline parmi les sciences
établies. Les mathématiciens considèrent l'informatique, au mieux,
comme un produit dérivé de l'analyse numérique, leur branche la plus "vulgaire". Les physiciens la mettent sur le même plan que l'art
de construire des appareillages pour les expériences. Pour les
biologistes, elle est au même niveau que la maîtrise de l'électrophorèse.
C, C++, Java et Perl
Vers les années 1987-88 il est, pour les raisons
sociologiques que nous venons de décrire,
devenu impossible dans la profession de programmer dans un
autre langage que C. Or C présente des inconvénients pratiques. 90 %
des problèmes de sécurité que l'on peut relever dans les avis du CERT
(2)
proviennent de l'exploitation des débordements de "buffers" par les pirates.
Ces débordements sont dus au fait que dans un programme en C le contrôle
des limites des zones de mémoire (vérifier qu'un parcours de tableau ne
franchit pas les bornes des indices) doit être fait laborieusement
« à la main ». Le plus souvent soit le programmeur ne fait pas ce contrôle, soit
il
le fait de façon erronée ; ce problème ne se poserait pas avec des
programmes en Ada, Java ou Scheme.
Pour corriger les défauts du C, on a créé C++. Lorsque je programmais
en C++, j'ai été tellement scandalisé par le mélange des choses de
haut et de bas niveau que j'ai inventé
l'expression « langage obscène » : l'obscénité procède de la juxtaposition
de choses qui doivent être séparées parce qu'elles relèvent de niveaux
d'abstraction différents, comme un manteau de fourrure sur un corps presque
nu, alors que ce dernier ne choquerait personne sur une plage du moins dans notre
culture. En C++, le programmeur est sans cesse rappelé
vers le bas, vers des problèmes dont il ne devrait pas
avoir à se soucier. En outre C++ est difficile à apprendre : il faut être
déjà compétent en C pour avoir une chance de pouvoir faire du C++. Au total, j'estime que l'apprentissage de
C++ constitue une perte de temps. Si l'on a besoin d'agir sur les
couches basses pour programmer un pilote de disque, une pile TCP/IP ou le kernel
Unix, on doit utiliser C ; si l'on ne veut pas agir sur les couches basses, C++
est inutile.
Puis on a vu apparaître Java. Il répond aux ambitions initiales de C++ qu'il nettoie de ses défauts les plus criants.
Java est un
langage propre, raisonnable, rassurant. On peut programmer en Java
sans se poser de question de bas niveau. Java n'apporte rien de nouveau,
d'où sans doute son succès. Toutefois il a un point
commun avec Perl, autre langage à succès de la fin des années 90 :
ils sont tous deux très inefficaces en termes de temps de calcul.
Perl est un autre exemple
de langage parfait pour ce pour quoi il a été conçu : traiter des fichiers
logs, automatiser les
tâches quotidiennes des ingénieurs système et produire le « tissu
conjonctif » entre de gros programmes écrits dans un autre langage
(par exemple pour construire un serveur Web). Mais il est calamiteux si l'on
doit aligner plus de quinze instructions. Or
beaucoup de gens peu ou mal formés utilisent Perl en dehors de
son biotope raisonnable parce qu'ils ne connaissent
rien d'autre. Dans ce genre, je préfère Python qui a les mêmes qualités que
Perl
en plus « clean ».
La programmation par l'utilisateur
Avec les outils comme Excel (ou SAS en statistique) on a vu arriver la programmation par l'utilisateur. On
a découvert qu'il est relativement facile pour l'utilisateur de
programmer des formules relevant de sa discipline. Ce qui lui est
difficile, c'est de programmer les liens entre les diverses parties d'un
logiciel de grande taille, c'est-à-dire de concevoir l'architecture
d'ensemble d'un programme complexe. Si on lui fournit une charpente prédéfinie il peut programmer sans
difficulté.
On a cru un temps que pour faciliter la programmation il
fallait utiliser des outils visuels, « programmer à la souris » sans
écrire de code. La véritable simplification ne réside
pas là. Ce qu'il faut faire pour simplifier la tâche du programmeur, c'est le soulager de la
conception de l'architecture d'ensemble du programme en fournissant une structure toute faite dont il
doit remplir les cases.
Langages "classiques" et langages
"modernes"
Les
langages " classiques" comme Pascal ou C comportent une allocation de
mémoire statique qui oblige à gérer explicitement la mémoire
dynamique. Le problème, c'est qu'alors toute erreur de gestion de la
mémoire induit une erreur lors de l'exécution du programme par
débordement de "buffer" ou par fuite de mémoire.
Ce qui caractérise les langages de haut niveau "
modernes", c'est la présence d'un gestionnaire de
cellules qui assure l'allocation et la libération des mémoires.
Algol est prémoderne, LISP est moderne ainsi qu'Ada et Java. Algol (1960) et
LISP (1959) ont eu du mal à s'imposer parce qu'à l'époque ils coûtaient cher
en termes d'efficacité ; celle-ci n'étant plus
prioritaire, leurs qualités ressortent mieux aujourd'hui.
Le destin de Pascal
J'ai longtemps utilisé Pascal, qui existe toujours sous le nom de
Delphi. Mais Pascal s'est évaporé. Il a été victime de deux ou trois
lacunes rédhibitoires dues à la rigidité des principes de son auteur,
Niklaus Wirth. Wirth ne voulait pas entendre parler de compilation
séparée (alors que cela n'aurait pas été compliqué). Pour lui, c'était un
péché de parler de tableaux de taille variable ; mais
dans Pascal la chaîne de caractère, dont la taille est par nature variable, est un tableau ! Borland a
fourni avec Turbo Pascal les
compléments nécessaires pour rendre Pascal confortable, mais il
n'existe pas de bon compilateur Pascal sous Unix.
Pascal s'est
cantonné à un monde particulier. Il s'est dilué, évaporé, fragmenté à
cause des partis pris de Wirth : des auteurs de compilateur ont
réalisé des extensions pour pallier les partis pris du maître, mais comme
elles n'ont pas été reconnues par tous le langage a divergé en multiples
variantes.
Les gens qui conçoivent les langages
ont toujours des préjugés auxquels ils
tiennent.
Chaque concepteur a ses petites manies. Ainsi on ne peut pas passer une procédure en argument en Ada : Jean
Ichbiah était persuadé que ce serait lourd et coûteux alors que, d'après un
autre membre de l'équipe de conception du langage, cela aurait été assez
simple à faire. D'un autre côté il a
introduit dans Ada a une fonction puissante de traitement de tableaux par
tranches qui, à elle seule, représente 25 % du code du compilateur.
Un bon langage pour apprendre à programmer
Lorsque j'ai voulu faire des cours de programmation à l'institut Pasteur j'ai essayé
d'utiliser Ada mais c'est un langage trop compliqué. Il
faut 20 heures de cours de syntaxe avant de pouvoir montrer aux
étudiants les possibilités les plus simples d'Ada ; l'enseignement de
la syntaxe est fastidieux et intellectuellement stérile. Ada a eu
pendant un temps du succès dans l'enseignement de l'informatique en raison de
sa séduction intellectuelle aux yeux des enseignants,
mais la lourdeur des compilateurs, leur prix et leur indisponibilité
dans les environnements les plus accessibles ont eu raison des
vocations pédagogiques les plus acharnées.
Scheme est par contre facile à enseigner ; comme il a une syntaxe
simple et régulière il séduit les étudiants en peu de temps, et le temps
que l'on ne perd pas à apprendre les obscurités de la syntaxe peut
servir à apprendre
à programmer. Les programmes en
Scheme sont raisonnablement faciles à relire, contrairement aux programmes
en C++. Scheme a ainsi vocation à remplacer Pascal dans la formation.
J'ai découvert Scheme en lisant le livre d'Abelson et Sussmann, Structure and Interpretation of Computer Programs,
MIT Press 1996 (en abrégé
« SICP »). Ce livre a fait beaucoup pour le succès de Scheme. J'ai suivi le premier
cours sur Scheme à l'institut Pasteur ; il était très beau mais incompréhensible. J'ai repris le cours
à ma façon, et les élèves y ont appris à programmer.
Faut-il programmer en objet ou pas ?
L'introduction des
objets a été utile car il fallait une rupture dans les
habitudes de programmation. Maintenant c'est fait. Le langage à
objets le plus pur est Smalltalk avec les méthodes dans les classes
etc. C'est un langage original, beau et puissant, mais il est difficile d'envisager
son usage pour de grands systèmes. Chaque fois que l'on crée un objet il hérite les
méthodes de la classe et devient énorme. J'ai utilisé des systèmes
objet pour Scheme : ils ont recours aux fonctions génériques, c'est plus
efficace que les méthodes dans les instances.
L'idéologie des objets comportait beaucoup... d'idéologie.
Il s'agissait de modéliser le monde réel : l'objet tracteur appartient-il
à la classe " véhicule automobile", ou à la classe " matériel aratoire" ?
S'il appartient aux deux, il faut de l'héritage multiple,
cauchemar pour les créateurs de langages. En fait dans l'écriture
d'un programme on ne simule pas des objets du monde réel mais
on structure et organise de l'information sur ces objets. Une fois
qu'on cesse de délirer en parlant de modélisation du réel, on voit
que l'héritage simple est non seulement plus facile que l'héritage multiple,
mais qu'il lui est préférable parce que l'information
se traite mieux selon une structure en arbre que selon un graphe connexe
quelconque.
Au bout du compte ce
que l'on fait avec les objets n'est pas très
différent de ce que l'on faisait en Ada avec les typages et
sous typages. L'encapsulation n'existait pas en Pascal, mais elle
existe en Ada, en Delphi, en Scheme ainsi que dans tous
les langages modernes. Bref, il faut programmer avec l'idée de l'objet, ce qui n'implique pas forcément une technologie
particulière.
(1) "Language comparisons are rarely
meaningful and even less often fair. The authors try hard to be impartial, but
are hopelessly biased by focusing on a single application, a single style of
programming, or a single culture among programmers" (Bjarne Stroustrup, The
design and Evolution of C++, Addison Wesley 1994, p. 5.)
(2) Le CERT ("Computer Emergency Response
Team") a été créé en novembre 1988 par la DARPA ("Defense Advanced
Research Projects Agency") pour répondre à des attaques de l'Internet par
des virus. Le CERT traite les questions de sécurité en diffusant des alarmes
et des méthodes pour traiter ou éviter les incidents. Il fait partie du
"Software Engineering Institute" de l'Université Carnegie-Mellon à
Pittsburgh.
Nota Bene : après avoir lu cet article,
Jean-Paul Figer m'a envoyé le message sarcastique que l'on trouvera à la date
du 11/12/01 parmi les commentaires des
lecteurs du site : "Programmer en
2001, c'est comme construire un ordinateur à partir de transistors. Il faut
avoir du temps à perdre. Ce n'est pas une tâche pour l’utilisateur."
Jean-Paul a raison, comme souvent, mais je ne partage pas son
avis. L'automobiliste ne construira jamais d'automobile, mais il s'intéresse à la
mécanique pour pouvoir choisir le modèle qui lui convient - et il est utile
d'avoir chez soi un petit atelier et des outils pour travailler le métal, le
bois, l'électricité, faire un peu d'électronique etc. Une dame
élégante ne sait pas tenir une aiguille mais sait parler métier avec son
couturier. De même, s'il est certain que le maître d'ouvrage ne sera jamais
un programmeur (à chacun son métier), il est bon
qu'il fasse de la programmation son hobby : comment, autrement,
comprendrait-il ce que lui racontent les SSII quand elles lui parlent de
"concurrence", de "thread", de "middleware" et
autres termes de métier ? comment pourra-t-il entrevoir ce que doit faire un
EAI ? comment pourra-t-il choisir le meilleur fournisseur ? et comment
pourra-t-il percevoir, lorsqu'il pense à la stratégie de l'entreprise,
l'étendue et les limites des apports du SI ?
|