Dans la première partie
de cet article, Dave s'en prenait à certaines idées reçues et dénonçait un
insidieux terrorisme intellectuel. Ce mois-ci, Dave continue le massacre en
s'attaquant entre autres au langage C. Inutile de dire qu'à la rédaction de
ST-Mag, cela fait grincer pas mal de dents, car les grands programmeurs que
nous côtoyons ont tendance à oublier les difficultés qu'ils éprouvèrent
lorsqu'ils étaient débutants. Dave en profite aussi pour égratigner la mode du
langage "politiquement correct" qui fait fureur outre-Atlantique et semble
gagner nos rivages. Dave a spécialement écrit pour les lecteurs de ST-Mag une
petite explication de ce phénomène...
J'en ai pIus qu'assez du langage C. J'ai codé en C et c'est pour moi
aussi intuitif et agréable que de changer une couche sale. Et
pourtant, les bidouilleurs considèrent que le C et son successeur
orienté objet, le C++, sont les langages de base. AAARGH !
Mais désormais, d'autres que moi critiquent le C. J'ai eu récemment le
plaisir de lire Jerry Pournelle [NdT :
journaliste du mensuel américain Byte et auteur de S] le
mettre à mal. Le problème de fond est que les programmeurs, presque
tous du type de personnalité NT, adorent le C pour ses pointilleux
casse-tête logiques, alors que c'est précisément ce que détestent les
autres types de personnalité - dont les N, le type des artistes et
écrivains, auquel j'appartiens. Les gens qui ne sont pas des
programmeurs professionnels sont souvent d'un type autre que NT. Or
les non-NT représentent 90% de la population.
Qu'est-ce que ça implique pour votre marché potentiel si vous décidez
de faire des langages de programmation? Soyez réalistes! Voulez-vous
viser 10% des gens ou 90% ?
Vous avez déjà vu des programmes en C ? lls sont bourrés de
casse-tête logiques qui, selon les études psychologiques, sont le
régal des NT. ll est même fréquent de voir des sources en C presque
totaement dénués de commentaires : allons donc, ce serait de la
triche! Un petit exemple bien connu nous est donné par une routine en
C tirée du noyau d'Unix, dont le commentaire dit : "Je ne m'attends
pas à ce que vous compreniez ce que je fais, alors je ne vais pas
essayer de l'expliquer." C'est pour moi l'exemple parfait d'un
programme en C.
Tenez, faites-vous donc les dents sur cette instruction d'une ligne en
C. Attention : ceci est considéré comme simple, élémentaire, facile
et enfantin par les maîtres du C.
while ( *ptr2++ = *ptr1++ ) ;
Question : que fait cette instruction ?
NB : j,espère que je n'ai pas fait d'erreur en écrivant cette ligne,
parce que le C est si incroyablement pinailleur que je ne m'en
souviens jamais assez pour écrire du code. [NdT
cette ligne est parfaitement correcte.] Un langage ne devrait
pas être si difficile à mémoriser. J'ai appris le Basic à 16 ans, et à
33, je m'en souviens encore.
Alors, que fait cette ligne? Eh bien, c'est un casse-tête logique ! Et
à moins de pouvoir le résoudre, vous n'êtes pas un Vrai Bidouilleur
(ou Bidouilleuse)... La foule vous observe ! Le suspense monte !
J'attends ! Alors ?...
Vous avez trouvé ?... Non ?... Alors, coupez-moi cette queue de
cheval, crétin ! Allez vous raser et prenez une douche! Et dégagez!
Permettez-moi de vous expliquer ce que fait ce code. Ptr2 et ptr1 sont
des pointeurs, c'est-à-dire qu' ils désignent un emplacement mémoire,
et contiennent l'adresse d'un octet. l' astérisque qui les précède
veut dire que l'on travaille non pas avec les adresses elles-mêmes,
mais avec le contenu des adresses. Le signe égal entre les deux
(l'affectation) signifie qu'on copie le contenu de l'emplacement
mémoire pointé par ptr1 dans celui pointé par ptr2. Le ++ qui suit les
noms des pointeurs veut dire que nous ajoutons automatiquement une
unité à chacun après usage, si bien qu'ils pointeront tous deux sur
l'emplacement mémoire suivant. Si ptr1 valait 1, il vaudra 2 après
exécution de ptr++. ce qui s'appelle l'auto-incrémentation.
Mais nous sommes dans une boucle "while", qui continue à s'exécuter
tant que la condition à l'intérieur de la parenthèse est vraie. Ce
n'est que lorsqu'elle devient fausse que l'on passe à l'instruction
suivante. C'est en somme une boucle I-THEN-GOTO (horreur! ). Donc,
cette instruction copie vers l'adresse ptr2 ce qu'il y a à l'adresse
ptr1, passe aux adresses suivantes, et continue jusqu'à ce que la
condition soit fausse. En C, faux équivaut à 0. Or, il se trouve que
les chaînes de caractères sont, par convention, délimitées en C par un
zéro ! (Ce qui entre en conflit avec la convention du Pascal, pour
lequel une chaîne commence par un entier donnant sa longueur. Vous ne
pouvez imaginer combien on s'amuse quand on veut, dans un programme en
C, appeler des routines en Pascal traîtant des chaînes... Comme quand
on programme sur Macintosh. C'est l'enfer. Beaucoup de programmes
plantent en ne trouvant jamais la fin d'une chaîne dont il manque le
zéro final.)
Donc la boucle "while" se termine lorsqu'elle rencontre le 0 de fin de
chaîne, parce que 0 équivaut à faux ! Et... j'en tremble
d'excitation... puisque ptr1 et ptr2 pointent sur des chaînes... Nous
venons de copier une chaîne !...
Super ! Génial ! C'est-y pas futé comme ruse, hmmm ? (Au fait, vos
cheveux ne vous démangent pas quand vous ne les lavez qu'une fois par
mois ?)
Si vous pensez que cette instruction est simple et élégante, apprenez
le C. Vous serez heureux de passer le reste de votre vie à déchiffrer
du code qui a délibérément été écrit pour être difficile à
comprendre. Vous adorerez l'absence de commentaires parce que "le code
est auto-commenté", ce qui revient à dire que si vous êtes trop bête
pour comprendre, par télépathie, ce que pensait l' auteur du code,
c'est que vous n'êtes pas à votre place. Ca me rappelle ce que
répondait ie miiliardaire J.P. Morgan, quand des invités montaient à
bord de son yacht et lui demandaient combien avait coûté le navire :
"S'il vous faut demander son prix, c'est que c'est au-dessus de vos
moyens."
Pour moi, cette ligne se résume tout simplement à une instruction A$ =
B$ en Basic, ce malheureux langage obsolète pour esprits primitifs
(comme dirait Spock, l'archétype du NT). Comme moi.
En fait, à moins de comprendre que la boucle "while" prendra fin
lorsqu'elle rencontrera un zéro de fin de chaîne, vous êtes perdu. Et
croyez-moi, je vous assure qu'il y a de très nombreux cas où une
chaîne peut perdre sa terminaison, causant un plantage. J'en ai tracé
tant... Le C est bourré d'aberrations de ce genre. De plus, il est
fait pour des gens qui ont peur de frapper un caractère en trop. La
boucle ci-dessus pourrait être "expansée" pour être plus claire, comme
par exemple :
/* Tant que ptr1 ne pointe pas
Mais l'écrire ainsi serait trop long. De même, pour ajouter un nombre
b à un nombre a, au lieu d'écrire
a = a + b;
le vrai codeur en C écrira
a += b;
Crétonnerre, mais c'est qu'on a économisé la frappe de deux caractères
en procédant ainsi !
Pour comparer deux variables, comme dans l'instruction Basic | A = B,
on doit en C utiliser une parenthèse et un double égal :
if (a == b) .
Et ce, à cause d'un subtil distinguo d'informaticien théoriste qui
affirme qu'il faut marquer une différence entre le signe égal qui sert
à transférer une donnée (l'affectation, A = B) et la comparaison (le
test, est-ce que A = B ?). Néanmoins, écrire if (a = b) en C
n'engendre pas d'erreur à la compilation, et se contente de semer la
panique dans votre programme ! Tous les programmeurs en C sont tombés
dans ce piège plus d'une fois.
Or, curieusement, la torture qu'ils s'infligent est considérée comme
un signe honorifique et est qualifiée de " bonne". Ce qui me rappelle
furieusement les religieux fanatiques se flagellant durant l'épidémie
de peste noire du XIVè siècle, en espérant que s'ils s' infligeaient
assez de tourments, Dieu leur épargnerait la peste parce qu'ils
avaient déjà assez souffert.
Si vous n'êtes pas encore mort de rire, sachez qu' il y a des
discussions ô combien sérieuses sur le temps que les programmeurs en C
ont gagné en utilisant ces petits raccourcis, comme si les
années-hommes de débogage ne comptaient pas. Et si toutes ces
turpitudes du C vous emplissent d' un sain dégoût, un peu comme quand
on observe le Parlement en action, alors, ami lecteur, apprenez et
utilisez le Basic et l'assembleur. Vous avez la chance d'avoir à votre
disposition sur le ST les Basic les plus puissants jamais écrits,
ainsi que le langage assembleur 68000, qui est le plus propre, le
mieux conçu, le plus facile à apprendre que l'on puisse imaginer. Si
vous avez déjà souffert sur l'infernal langage-machine du 8088 des
compatibles PC, qui est une abomination vomie par le démon, vous êtes
probablement dégoûté de l'assembleur. Aussi, je vous en prie, essayez
ce pur, ce merveilleux assembleur 68000 (GenSt et GenTT de HiSoft sont
formidables). C'est un plaisir, et les gens qui l' utilisent en
tombent amoureux (comme moi).
Récemment, un torch... heu... un magazine consacré au PC a sondé ses
lecteurs pour savoir dans quel langage ils programmaient. Les
rédacteurs ont dressé une liste comprenant les langages C, Pascal,
Modula, Assembleur, Forth et autres... Quelqu'un fit alors timidement
remarquer qu'un brave bouseux nommé Small habitant Denver, dans le
Colorado, pourrait bien encore utiliser le Basic. Tous eurent un petit
rire dédaigneux et ajoutèrent le Basic "pour compléter la liste".
Je dois préciser que les rédacteurs techniques sont presque
exclusivement des NT. Les autres rédacteurs et écrivains sont des N.
Quand les réponses des lecteurs commencèrent à arriver, la rédaction
était pâle et tremblante d'horreur. L'énorme majorité des lecteurs
programmait en lBM Basic ou en GW-Basic ! C'était à n'y rien
comprendre. Comment, avec tous les avantages qu'offrait le C, il
fallait être un troglodyte criminel pour utiliser le Basic ! Mais le
fait était que beaucoup de gens, y compris votre serviteur, emploient
le Basic. ll faut être masochiste pour utiliser le C. Vous
haïssez-vous vraiment ?
Les médias arrivent ainsi parfois à s'autopersuader que le petit
terrorisme intellectuel qu'ils imposent dans leur domaine est obéi par
le public. Dans ce cas-là, le démenti fut cinglant. Mais sous d'autres
formes, la remise des pendules à l'heure tarde à venir. Comme par
exemple pour la vague du " politiquement correct" qui sevit aux
USA. Une "Personne Correcte Politiquement, , (PCP) ne fera pas
l'aumône à un aveugle mais "apportera une aide humanitaire à une
personne visuellement handicapée", ne parlera pas d'un vieillard mais
d' une "personne du troisième âge", et autres
non-sens. Personnellement, je pense que cette "langue de coton" permet
de répartir les gens en catégories pour les contrôler plus facilement,
ce que je déteste. ll faut se rappeler que PCP désigne en chimie la
phencyclidine, un puissant anesthésique pour animaux que fument les
drogués, et qui provoque chez eux de redoutables hallucinations les
coupant totalement de la réalité. Voilà une belle métaphore pour ce
conformisme servile.
Le basic n'est pas obsolete
Jadis, durant les années 1960, c'est-à-dire il y a tout de même trente
ans, le Basic vous permettait d'abuser de certaines choses, comme
l'instruction GOTO. Si vous étiez idiot, vous écriviez du "code
spaghetti", où le flot du programme partait dans tous les sens. Mettre
fin à ces abus devint apparemment le but dans l'existence du
Pr. Wirth. Mais il jeta le bébé avec l'eau du bain : le Basic était
extrêmement puissant comparé au Pascal.
Loi de Small n° 21 : on peut écrire du mauvais code dans n'importe
quel langage, y compris le C et le Basic. Mais de plus, le C est
orienté vers le "code à écriture seule", par analogie avec les ROM qui
sont des mémoires à lecture seule.
Loi de Small n° 22 : du "code à écriture seule" est du code si
illisible qu'il ne pourra jamais plus être déchiffré, même par son
auteur trois mois après. Le langage APL est l'exemple classique en la
matière, mais le C n'est pas mal non plus.
Loi de Small n° 23 : Ecrire pour votre entreprise du "code à écriture
seule" dont vous gardez en secret une version commentée s'appelle
"prendre une assurance anti-licenciement".
Loi de Small n° 24 : Le logiciel de l'IRS (le service de l'impôt sur
le revenu américain) a été écrit par des gens qui sont souvent morts
aujourd,hui. ait authentique : parfois, les structures fiscales ne
peuvent être changées parce que personne ne sait plus où faire les
modifications dans le logiciel. l'IRS continue à embaucher des
programmeurs.
Pour en revenir au Basic des années 60, on pouvait très bien abuser de
l' instruction GOTO, tout comme l'auteur d'un article peut très bien
abuser des digressions et parenthèses pour s'écarter du
sujet... Hem... heu... Reprenons.
Des gens bien inspirés ajoutèrent au Basic ce qui était alors le nec
plus ultra, entre autres les structures de programmation, de sorte
qu'on pouvait les utiliser si on le désirait. J'estime quant à moi que
se prosterner devant les diktats de la programmation structurée est
idiot. Mais peut-être votre compagnie a-t-elle des règlements stricts,
disant que vous devez être à votre bureau à 9 h, vous laver les mains
après avoir été aux toilettes, et utiliser des boucles " while" au
lieu de IF-THEN-ELSE. Dans ce cas, pauvre hère, toutes mes
condoléances.
Et si jamais un comique vous dit que le Basic est obsolète, voici
quelques questions à lui poser pour engager la conversation:
Quand je veux écrire quelque chose très vite, je l'écris en Basic, qui
est une sorte de super-assembleur et qui fait pour vous beaucoup de
travaux fastidieux. Quand je veux faire un programme qui va le plus
vite possible, je l'écris en assembleur, et il pulvérise tout ce qui
peut être écrit en d'autres langages. Je n'écris pas des saletés qui
se traînent à la même allure que ce que peut faire n'importe qui,
allure qui n'a guère changé depuis 1980. (Vous savez, la même vitesse
de défilement affligeante, la même vitesse de recalcul
gastéropodesque...)
Loi de Small n° 25 : Tandis que le matériel devient de plus en plus
rapide, les programmeurs engendrent un code de plus en plus mauvais,
de sorte que la vitesse d'exécution reste constante. Le code engendré
par les compilateurs C++ modernes, par exemple, est incroyablement
inefficace. Je vous défie de me contredire après avoir utilisé System
7.0 sur un Mac à 8 MHz.
Loi de Small n° 26 : La raison pour laquelle Windows 3.0 est considéré
comme " utilisable" est qu'il tourne désormais en général sur de
puissants 386 ou 486 à plus de 16 MHz. l'ancienne version de Windows,
qui fut condamnée par la presse comme étant "trop lente", ne
bénéficiait pas encore de ce matériel. Je parie que Microsoft s'est
contenté d'attendre ! Windows n'est d'ailleurs pas codé en assembleur.
Loi de Small n° 27 : Un programmeur digne de ce nom peut créer des
codes époustouflants en assembleur, car rien qu'en évitant les
grossières inefficiences des générateurs de code du C ou du Pascal, le
programme sera beaucoup plus rapide. C'est ainsi que l'on crée des
légendes. Prenez l'éditeur de texte Tempus, vous avez vu sa vitesse de
défilement ? !
Loi de Small n° 28 : Comment croyez-vous que j'ai fait un émulateur
Mac ? A votre avis, pourquoi est-il si rapide ?
Loi de Small n° 29 : Pensez-vous que l'on puisse gagner sa vie en
suivant le troupeau du conformisme ? Si un avis est donné gratuitement
dans un magazine, il vaut probablement ce que vous l'avez payé.
Ben voyons. Si un bidouilleur du C vous affirme cela, regardez-le
droit dans les yeux et faites-le répéter Je sais ce ce qu'il en est,
j'ai fait des portages de sources C. C'est presque aussi amusant que
de désenliser sous la pluie une voiture qui a de la boue jusqu'aux
portières.
En théorie, vous devriez pouvoir prendre un code source écrit en C sur
une machine et le recompiler sans problème sur une autre. A vrai dire,
un source en C est partiellement portable entre machines. Pour l'être
totalement, le source devrait n'utiliser que le plus petit commun
dénominateur entre les machines, ce qui veut dire qu'il ne pourrait
utiliser par exemple les caractéristiques parti- culères du ST. Ou
alors, il faut recourir à l'écriture de modules "pilotes" spéciaux, ce
qui réfute l'idée même de portabilité.
Et si vous réussissez à faire votre portage entre deux machines ? En
ce cas, bravo ! Vous avez maintenant deux machines se traînant bien en
deçà de leur vitesse optimale, parce que les compilateurs C sont
encore très peu malins quand ils engendrent le code
machine. Rappelez-vous que les compilateurs ne sont que des programmes
et n' ont en eux rien de l'intelligence humaine pour les aider à
optimiser. [NdT : sur station de travail Unix,
certains compilateurs disposent d'optimiseurs qui, eux, appliquent des
astuces de programmeurs chevronnés pour améliorer leur code
machine.] Je dirais que la science des compilateurs a encore
besoin de 50 ans de progrès avant de concurrencer les codeurs
humains. Pour l'instant, n'importe quel programmeur peut améliorer
considérablement du code compilé.
Note : la "remarquable augmentation de vitesse" des ROM 128K du Mac
par rapport aux 64K est due à un programmeur qui a réécrit en
assembleur les routines du Quickdraw compilées en Pascal.
Bref, je suis persuadé que faire un programme qui se traîne sur deux
machines n' est pas un exploit. Le faire foncer, voilà qui est bien !
Prenez le très portable X-Windows, l'environnement graphique pour
stations de travail. Il est admis par presque tous que ce système est
lent, lourd et très touffu. Il faut des processeurs graphiques
spécialisés pour avoir des vitesses acceptables, ce qui fait le
bonheur des fabricants de puces. [NdT : il est
vrai qu'il faut des machines d'au moins 20 MlPS pour avoir sous
X-Windows des vitesses de réaction comparables à celles du GEM sur
ST.]
Maintenant que j'y pense, je signale que le Basic de l'IBM PC est
plutôt rapide, et plutôt portable... même sur le ST.
La vérité est qu'il y a un hiatus entre un concept et son
implémentation, à savoir la programmation structurée.
Structurer un programme, tout programmeur sain d'esprit le fait, mais
pas forcément dans la forme imposée par le terrorisme intellectuel
ambiant. Tenez, mon style particulier de structuration est que le
début d'un programme est la première chose qu'il fait, la dernière
ligne est la dernière chose. Si je débogue quelque chose qui est fait
à mi-chemin dans le programme, je commence par regarder au milieu du
listing. Oui, j,utilise des sous-programmes, je les mets d'habitude au
bas du listing, mais aussi parfois près de la routine qui les
utilise. Cela rend le débogage beaucoup plus facile, ce qui me permet
d'achever le programme plus vite.
La structure des programmes Pascal me paraît insensée. Elle est sens
dessus-des- sous. d'abord, vous devez écrire tous les
sous-programmes. Ensuite, au fin fond du listing, vous écrivez le code
qui les appelle. Et c'est censé être cela, la programmation
"haut-en-bas" ? Calembredaines ! Oui, je sais que le Pascal est un
compilateur monopasse, mais c'est une mauvaise excuse, mon
gaillard.
Ensuite, n'oubliez pas que la structure, c'est votre affaire, pas
celle de Wirth (et je suis certain qu'il m'approuverait). Vous pouvez
écrire de l'assembleur structuré qui est facile à déboguer si vous le
souhaitez. Ou bien vous pouvez pondre le plus abominable des plats de
spaghettis en C si vous le voulez, et le soumettre à vos confrères
dans le cadre des concours "Que fait ce code?" organisés chaque
année, où des bouts de codes particulièrement obscurs sont soumis à la
sagacité de programmeurs C.
Le langage dans lequel vous codez n'a rien à voir avec vos capacités
de bidouilleurs. Un langage de programmation est censé être une façon
conventionnelle de donner des instructions à un ordinateur, et doit
pouvoir être écrit et relu par des personnes différentes. ll n'est pas
censé être obscur, bizarre et plein de pièges subtils (ça, ce sont les
attributs de la magie). Ce qui importe en matière de créativité, ce
sont vos rêves et votre volonté de repousser les limites, de faire ce
que personne ne croyait possible (un bon exemple est fourni par
presque toutes les créations de Codehead Software). Le reste n'est que
vaine discussion entre peintres pour savoir quel pinceau est le
meilleur. Certes, il se trouve des gens pour apprécier ces
discussions, mais elles ne sont guère au coeur du débat.
Et si vous tenez absolument à ce que vos créations portent le fardeau
que ne manquera pas de leur imposer le C, c'est votre affaire,
allez-y. Moi, je dis seulement que je préfère voir ma machine dépenser
utilement chaque cycle d'unité centrale.
Alors, rebellez-vous. A la prochaine réunion de votre groupe
d'utilisateurs, interrompez les monologues des gourous du C, et dites
: "Moi, je pense que le C est inutilisable et qu'on s'en souviendra
comme d'un cauchemar dans dix ans. Quant aux structures, c'est moi
qui les utilise, et non l'inverse."
Voyez ce qui arrivera. Vous devrez peut être couper votre queue de
cheval, vous doucher et vous raser. Mais vous serez alors un véritable
bidouilleur.
Si vous voulez me lancer des tomates, voici mes adresses télématiques
:
GEnie : DAVESMALL
J'espère que cet article vous a plu, même si vous n'êtes pas
d'accord. J'attends en tout cas vos commentaires. A la prochaine fois!
Traduction et adatation : Password
Titre original: Heresy
Tout le monde trouve le langage C facile, sauf
les crétins
Un casse-tête en C
sur le caractère de code 0
*/
while ( *ptr1 ! = ' \0 ' )
{
*ptr2 ++ = *ptr1 ++; /*
Copie
avec auto-incrémentation */
}
Le sondage
Médias hallucinés
Parce que le malheureux en est irrémédiablement resté aux années 60.
Mais, Dave, le C est portable
La verite
Je veux utiliser un langage dans lequel je puisse donner des ordres à
la machine, et non me livrer à des contorsions pour lui faciliter la
tâche.
De même, structurer un article, tout auteur sain d'esprit le fait,
mais pas forcément de manière conformiste. Le "flot de contrôle" de
l'article ne doit pas être exagérément obscurci par des digressions,
des écarts et des considérations hors- sujet. J'ai délibérément écrit
cet article de manière non structurée, en y ajoutant force
digressions, de manière à bien montrer l'analogie avec la
programmation. Dans d'autres articles, je vais rigoureusement du début
à la conclusion de manière linéaire, ce qui montre que je peux aussi
écrire - ou coder - de manière structurée. Mais l'important, c'est le
plaisir du lecteur. A votre avis, de l'agrément ou de la rigueur,
qu'est-ce qui prime ?
Rebellez vous
La cible de vous tomate
Compuserve: 76606,666 ou 76004,2136
Internet/USENET :dsmall@well.sf.ca.us