LE LANGAGE CENTENAIRE
OriginalAvril 2003
(Cet essai est tiré d'un discours prononcé à PyCon 2003.)
Il est difficile de prédire à quoi ressemblera la vie dans cent ans. Il n'y a que quelques choses que nous pouvons dire avec certitude. Nous savons que tout le monde conduira des voitures volantes, que les lois de zonage seront assouplies pour permettre la construction de bâtiments de plusieurs centaines d'étages, qu'il fera sombre la plupart du temps et que toutes les femmes seront formées aux arts martiaux. Ici, je veux zoomer sur un détail de cette image. Quel type de langage de programmation utiliseront-ils pour écrire le logiciel qui contrôle ces voitures volantes ?
Cela vaut la peine d'y réfléchir, non pas tant parce que nous allons réellement utiliser ces langages, mais parce que, si nous avons de la chance, nous utiliserons des langages sur le chemin qui mène de ce point à celui-là.
Je pense que, comme les espèces, les langages formeront des arbres évolutifs, avec des impasses qui se ramifient partout. Nous pouvons déjà voir cela se produire. Cobol, malgré sa popularité parfois, ne semble pas avoir de descendants intellectuels. C'est une impasse évolutive - un langage néandertalien.
Je prédis un sort similaire à Java. Les gens me font parfois parvenir des courriels disant : "Comment pouvez-vous dire que Java ne sera pas un langage réussi ? C'est déjà un langage réussi." Et j'admets que c'est le cas, si vous mesurez le succès par l'espace sur les étagères occupé par les livres qui y sont consacrés (en particulier les livres individuels qui y sont consacrés), ou par le nombre d'étudiants de premier cycle qui pensent devoir l'apprendre pour trouver un emploi. Lorsque je dis que Java ne sera pas un langage réussi, je veux dire quelque chose de plus précis : que Java sera une impasse évolutive, comme Cobol.
Ce n'est qu'une supposition. Je peux me tromper. Mon but ici n'est pas de dénigrer Java, mais de soulever la question des arbres évolutifs et d'amener les gens à se demander où se trouve le langage X sur l'arbre. La raison de poser cette question n'est pas seulement pour que nos fantômes puissent dire, dans cent ans, je vous l'avais dit. C'est parce que rester près des branches principales est une heuristique utile pour trouver des langages qui seront bons à programmer maintenant.
À un moment donné, vous êtes probablement le plus heureux sur les branches principales d'un arbre évolutif. Même lorsqu'il y avait encore beaucoup de Néandertaliens, cela devait être pénible d'en être un. Les Cro-Magnons devaient constamment venir vous frapper et vous voler votre nourriture.
La raison pour laquelle je veux savoir à quoi ressembleront les langages dans cent ans, c'est pour savoir sur quelle branche de l'arbre miser maintenant.
L'évolution des langages diffère de l'évolution des espèces parce que les branches peuvent converger. La branche Fortran, par exemple, semble fusionner avec les descendants d'Algol. En théorie, cela est possible pour les espèces aussi, mais il est peu probable que cela se soit produit pour des espèces plus grandes qu'une cellule.
La convergence est plus probable pour les langages, en partie parce que l'espace des possibilités est plus petit, et en partie parce que les mutations ne sont pas aléatoires. Les concepteurs de langages intègrent délibérément des idées d'autres langages.
Il est particulièrement utile pour les concepteurs de langages de réfléchir à l'endroit où l'évolution des langages de programmation est susceptible de mener, car ils peuvent s'orienter en conséquence. Dans ce cas, "rester sur une branche principale" devient plus qu'un moyen de choisir un bon langage. Il devient une heuristique pour prendre les bonnes décisions concernant la conception des langages.
Tout langage de programmation peut être divisé en deux parties : un ensemble d'opérateurs fondamentaux qui jouent le rôle d'axiomes, et le reste du langage, qui pourrait en principe être écrit en termes de ces opérateurs fondamentaux.
Je pense que les opérateurs fondamentaux sont le facteur le plus important de la survie à long terme d'un langage. Le reste, vous pouvez le changer. C'est comme la règle qui dit que pour acheter une maison, il faut d'abord tenir compte de l'emplacement. Tout le reste, vous pouvez le réparer plus tard, mais vous ne pouvez pas réparer l'emplacement.
Je pense qu'il est important non seulement que les axiomes soient bien choisis, mais qu'il y en ait peu. Les mathématiciens ont toujours ressenti cela à propos des axiomes - moins il y en a, mieux c'est - et je pense qu'ils ont raison.
Au minimum, il faut que ce soit un exercice utile d'examiner de près le cœur d'un langage pour voir s'il y a des axiomes qui pourraient être éliminés. J'ai constaté dans ma longue carrière de fainéant que la crasse engendre la crasse, et j'ai vu cela se produire dans les logiciels comme dans les lits et dans les coins des pièces.
J'ai le pressentiment que les branches principales de l'arbre évolutif passent par les langages qui ont les noyaux les plus petits et les plus propres. Plus vous pouvez écrire un langage en lui-même, mieux c'est.
Bien sûr, je fais une grosse hypothèse en me demandant même à quoi ressembleront les langages de programmation dans cent ans. Serons-nous encore en train d'écrire des programmes dans cent ans ? Ne serons-nous pas simplement en train de dire aux ordinateurs ce que nous voulons qu'ils fassent ?
Il n'y a pas eu beaucoup de progrès dans ce domaine jusqu'à présent. Je suppose que dans cent ans, les gens diront encore aux ordinateurs ce qu'ils doivent faire en utilisant des programmes que nous reconnaîtrions comme tels. Il y aura peut-être des tâches que nous résolvons maintenant en écrivant des programmes et qui, dans cent ans, ne nécessiteront plus d'écrire des programmes pour être résolues, mais je pense qu'il y aura encore beaucoup de programmation du type que nous faisons aujourd'hui.
Il peut sembler présomptueux de penser que quelqu'un peut prédire à quoi ressemblera une technologie dans cent ans. Mais rappelez-vous que nous avons déjà près de cinquante ans d'histoire derrière nous. Regarder cent ans en avant est une idée saisissable si l'on considère la lenteur avec laquelle les langages ont évolué au cours des cinquante dernières années.
Les langages évoluent lentement parce qu'ils ne sont pas vraiment des technologies. Les langages sont des notations. Un programme est une description formelle du problème que vous voulez qu'un ordinateur résolve pour vous. Ainsi, le taux d'évolution des langages de programmation ressemble davantage au taux d'évolution des notations mathématiques qu'à, disons, le transport ou les communications. Les notations mathématiques évoluent, mais pas avec les sauts géants que l'on observe dans la technologie.
Quelle que soit la matière dont seront faits les ordinateurs dans cent ans, il semble sûr de prédire qu'ils seront beaucoup plus rapides que ce qu'ils sont maintenant. Si la loi de Moore continue de s'appliquer, ils seront 74 quintillions (73 786 976 294 838 206 464) fois plus rapides. C'est un peu difficile à imaginer. Et en effet, la prédiction la plus probable dans le domaine de la vitesse est peut-être que la loi de Moore cessera de fonctionner. Tout ce qui est censé doubler tous les dix-huit mois semble susceptible de se heurter à une sorte de limite fondamentale à terme. Mais je n'ai aucun mal à croire que les ordinateurs seront beaucoup plus rapides. Même s'ils ne finissent par être que d'un million de fois plus rapides, cela devrait changer les règles du jeu pour la programmation des langages de manière substantielle. Entre autres choses, il y aura plus de place pour ce que l'on considérerait aujourd'hui comme des langages lents, c'est-à-dire des langages qui ne produisent pas un code très efficace.
Et pourtant, certaines applications exigeront toujours de la vitesse. Certains des problèmes que nous voulons résoudre avec les ordinateurs sont créés par les ordinateurs ; par exemple, le taux auquel vous devez traiter des images vidéo dépend du taux auquel un autre ordinateur peut les générer. Et il existe une autre catégorie de problèmes qui ont intrinsèquement une capacité illimitée à absorber les cycles : le rendu d'images, la cryptographie, les simulations.
Si certaines applications peuvent être de plus en plus inefficaces tandis que d'autres continuent à exiger toute la vitesse que le matériel peut fournir, des ordinateurs plus rapides signifieront que les langages doivent couvrir une gamme d'efficacités toujours plus large. Nous avons vu cela se produire déjà. Les implémentations actuelles de certains nouveaux langages populaires sont incroyablement gaspilleuses selon les normes des décennies précédentes.
Ce n'est pas quelque chose qui n'arrive qu'avec la programmation des langages. C'est une tendance historique générale. Au fur et à mesure que les technologies s'améliorent, chaque génération peut faire des choses que la génération précédente aurait considérées comme un gaspillage. Les gens d'il y a trente ans seraient étonnés de voir avec quelle désinvolture nous passons des appels téléphoniques longue distance. Les gens d'il y a cent ans seraient encore plus étonnés qu'un paquet puisse un jour voyager de Boston à New York via Memphis.
Je peux déjà vous dire ce qui va arriver à tous ces cycles supplémentaires que le matériel plus rapide va nous donner dans les cent prochaines années. Ils vont presque tous être gaspillés.
J'ai appris à programmer lorsque la puissance des ordinateurs était rare. Je me souviens d'avoir enlevé tous les espaces de mes programmes Basic pour qu'ils tiennent dans la mémoire d'un TRS-80 de 4 Ko. Le fait de penser à tous ces logiciels stupidement inefficaces qui brûlent des cycles en faisant la même chose encore et encore me semble un peu dégoûtant. Mais je pense que mes intuitions ici sont fausses. Je suis comme quelqu'un qui a grandi pauvre et qui ne peut pas supporter de dépenser de l'argent même pour quelque chose d'important, comme aller chez le médecin.
Certains types de gaspillage sont vraiment dégoûtants. Les VUS, par exemple, seraient sans doute dégoûtants même s'ils fonctionnaient avec un carburant qui ne se tarir jamais et ne produisait aucune pollution. Les VUS sont dégoûtants parce qu'ils sont la solution à un problème dégoûtant. (Comment faire en sorte que les monospaces aient l'air plus masculins.) Mais tout gaspillage n'est pas mauvais. Maintenant que nous avons l'infrastructure pour le supporter, compter les minutes de vos appels longue distance commence à paraître mesquin. Si vous avez les ressources, il est plus élégant de considérer tous les appels téléphoniques comme une seule et même chose, quel que soit l'endroit où se trouve l'autre personne.
Il y a du bon gaspillage et du mauvais gaspillage. Je suis intéressé par le bon gaspillage - celui où, en dépensant plus, nous pouvons obtenir des conceptions plus simples. Comment allons-nous profiter des opportunités de gaspiller des cycles que nous aurons avec le nouveau matériel plus rapide ?
Le désir de vitesse est tellement profondément enraciné en nous, avec nos ordinateurs chétifs, qu'il faudra un effort conscient pour le surmonter. Dans la conception des langages, nous devrions rechercher consciemment des situations où nous pouvons échanger l'efficacité contre même la plus petite augmentation de la commodité.
La plupart des structures de données existent en raison de la vitesse. Par exemple, de nombreux langages aujourd'hui ont à la fois des chaînes de caractères et des listes. Sémantiquement, les chaînes de caractères sont plus ou moins un sous-ensemble de listes dans lesquelles les éléments sont des caractères. Alors pourquoi avez-vous besoin d'un type de données distinct ? Vous n'en avez pas vraiment besoin. Les chaînes de caractères n'existent que pour l'efficacité. Mais c'est nul d'encombrer la sémantique du langage avec des bidouilles pour faire tourner les programmes plus vite. Avoir des chaînes de caractères dans un langage semble être un cas de préoptimisation.
Si l'on considère le cœur d'un langage comme un ensemble d'axiomes, il est certainement dégoûtant d'avoir des axiomes supplémentaires qui n'ajoutent aucune puissance expressive, simplement pour des raisons d'efficacité. L'efficacité est importante, mais je ne pense pas que ce soit la bonne façon de l'obtenir.
La bonne façon de résoudre ce problème, je pense, est de séparer la signification d'un programme des détails de l'implémentation. Au lieu d'avoir à la fois des listes et des chaînes de caractères, n'ayez que des listes, avec un moyen de donner au compilateur des conseils d'optimisation qui lui permettront de disposer les chaînes de caractères comme des octets contigus si nécessaire.
Puisque la vitesse n'a pas d'importance dans la plupart d'un programme, vous n'aurez pas besoin de vous soucier de ce genre de microgestion. Cela sera de plus en plus vrai au fur et à mesure que les ordinateurs deviendront plus rapides.
Dire moins de choses sur l'implémentation devrait également rendre les programmes plus flexibles. Les spécifications changent pendant qu'un programme est en cours d'écriture, et ce n'est pas seulement inévitable, mais souhaitable.
Le mot "essai" vient du verbe français "essayer", qui signifie "essayer". Un essai, au sens original, est quelque chose que vous écrivez pour essayer de comprendre quelque chose. Cela se produit dans les logiciels aussi. Je pense que certains des meilleurs programmes étaient des essais, en ce sens que les auteurs ne savaient pas au début exactement ce qu'ils essayaient d'écrire.
Les hackers Lisp connaissent déjà la valeur d'être flexible avec les structures de données. Nous avons tendance à écrire la première version d'un programme de manière à ce qu'il fasse tout avec des listes. Ces versions initiales peuvent être tellement incroyablement inefficaces qu'il faut un effort conscient pour ne pas penser à ce qu'elles font, tout comme, pour moi du moins, manger un steak exige un effort conscient pour ne pas penser d'où il vient.
Ce que les programmeurs dans cent ans rechercheront, par-dessus tout, c'est un langage où vous pouvez assembler une version 1 incroyablement inefficace d'un programme avec le moins d'effort possible. Du moins, c'est comme ça que nous le décririons en termes d'aujourd'hui. Ce qu'ils diront, c'est qu'ils veulent un langage qui soit facile à programmer.
Les logiciels inefficaces ne sont pas dégoûtants. Ce qui est dégoûtant, c'est un langage qui oblige les programmeurs à faire un travail inutile. Gâcher le temps des programmeurs est la véritable inefficacité, et non le gaspillage de temps machine. Cela deviendra de plus en plus clair au fur et à mesure que les ordinateurs deviendront plus rapides.
Je pense que se débarrasser des chaînes de caractères est déjà quelque chose que nous pourrions envisager. Nous l'avons fait dans Arc, et cela semble être un gain ; certaines opérations qui seraient difficiles à décrire comme des expressions régulières peuvent être décrites facilement comme des fonctions récursives.
Jusqu'où ira cet aplatissement des structures de données ? Je peux penser à des possibilités qui me choquent même moi, avec mon esprit consciencieusement élargi. Allons-nous nous débarrasser des tableaux, par exemple ? Après tout, ce ne sont que des sous-ensembles de tables de hachage où les clés sont des vecteurs de nombres entiers. Allons-nous remplacer les tables de hachage elles-mêmes par des listes ?
Il y a des perspectives encore plus choquantes que cela. Le Lisp que McCarthy a décrit en 1960, par exemple, n'avait pas de nombres. Logiquement, vous n'avez pas besoin d'avoir une notion distincte de nombres, car vous pouvez les représenter comme des listes : le nombre entier n pourrait être représenté comme une liste de n éléments. Vous pouvez faire des mathématiques de cette façon. C'est juste incroyablement inefficace.
Personne n'a réellement proposé d'implémenter les nombres comme des listes dans la pratique. En fait, l'article de McCarthy de 1960 n'était pas, à l'époque, destiné à être implémenté du tout. C'était un exercice théorique, une tentative de créer une alternative plus élégante à la machine de Turing. Lorsque quelqu'un a, de manière inattendue, pris cet article et l'a traduit en un interpréteur Lisp fonctionnel, les nombres n'ont certainement pas été représentés comme des listes ; ils ont été représentés en binaire, comme dans tous les autres langages.
Un langage de programmation pourrait-il aller jusqu'à se débarrasser des nombres comme type de données fondamental ? Je pose cette question non pas tant comme une question sérieuse que comme un moyen de jouer au poulet avec l'avenir. C'est comme le cas hypothétique d'une force irrésistible rencontrant un objet immobile - ici, une implémentation incroyablement inefficace rencontrant des ressources incroyablement importantes. Je ne vois pas pourquoi pas. L'avenir est assez long. S'il y a quelque chose que nous pouvons faire pour réduire le nombre d'axiomes dans le cœur du langage, cela semblerait être le côté sur lequel miser lorsque t tend vers l'infini. Si l'idée semble encore insupportable dans cent ans, peut-être ne le sera-t-elle plus dans mille ans.
Pour être clair, je ne propose pas que tous les calculs numériques soient réellement effectués à l'aide de listes. Je propose que le langage de base, avant toute notation supplémentaire concernant l'implémentation, soit défini de cette manière. En pratique, tout programme qui voudrait faire un certain nombre de calculs mathématiques représenterait probablement les nombres en binaire, mais ce serait une optimisation, et non une partie de la sémantique du langage de base.
Une autre façon de brûler des cycles est d'avoir plusieurs couches de logiciels entre l'application et le matériel. C'est aussi une tendance que nous voyons se produire déjà : de nombreux langages récents sont compilés en bytecode. Bill Woods m'a dit un jour que, en règle générale, chaque couche d'interprétation coûte un facteur de 10 en vitesse. Ce coût supplémentaire vous procure de la flexibilité.
La toute première version d'Arc était un cas extrême de ce type de lenteur à plusieurs niveaux, avec des avantages correspondants. C'était un interpréteur "métacirculaire" classique écrit au-dessus de Common Lisp, avec une ressemblance familiale définie avec la fonction eval définie dans l'article original de McCarthy sur Lisp. Le tout ne faisait que quelques centaines de lignes de code, il était donc très facile à comprendre et à modifier. Le Common Lisp que nous utilisions, CLisp, fonctionne lui-même au-dessus d'un interpréteur de bytecode. Nous avions donc ici deux niveaux de interprétation, l'un d'eux (le niveau supérieur) étant incroyablement inefficace, et le langage était utilisable. À peine utilisable, je l'admets, mais utilisable.
Écrire des logiciels en plusieurs couches est une technique puissante même au sein des applications. La programmation ascendante signifie écrire un programme comme une série de couches, chacune servant de langage pour celle qui se trouve au-dessus. Cette approche tend à produire des programmes plus petits et plus flexibles. C'est aussi la meilleure voie vers ce Saint Graal, la réutilisabilité. Un langage est par définition réutilisable. Plus vous pouvez pousser votre application dans un langage pour écrire ce type d'application, plus votre logiciel sera réutilisable.
D'une manière ou d'une autre, l'idée de réutilisabilité s'est attachée à la programmation orientée objet dans les années 1980, et aucune quantité de preuves contraires ne semble pouvoir la faire lâcher prise. Mais bien que certains logiciels orientés objet soient réutilisables, ce qui les rend réutilisables, c'est leur caractère ascendant, et non leur caractère orienté objet. Considérez les bibliothèques : elles sont réutilisables parce qu'elles sont des langages, qu'elles soient écrites dans un style orienté objet ou non.
Je ne prédis pas la disparition de la programmation orientée objet, d'ailleurs. Bien que je ne pense pas qu'elle ait grand-chose à offrir aux bons programmeurs, sauf dans certains domaines spécialisés, elle est irrésistible pour les grandes organisations. La programmation orientée objet offre un moyen durable d'écrire du code spaghetti. Elle vous permet d'accroître les programmes comme une série de correctifs.
Les grandes organisations ont toujours tendance à développer des logiciels de cette manière, et je m'attends à ce que cela soit aussi vrai dans cent ans qu'aujourd'hui.
Tant que nous parlons d'avenir, nous devons parler de calcul parallèle, car c'est là que cette idée semble vivre. C'est-à-dire que, quelle que soit la date à laquelle vous parlez, le calcul parallèle semble être quelque chose qui va arriver dans le futur.
L'avenir va-t-il jamais le rattraper ? Les gens parlent du calcul parallèle comme de quelque chose d'imminent depuis au moins 20 ans, et cela n'a pas beaucoup affecté la pratique de la programmation jusqu'à présent. Ou pas ? Déjà les concepteurs de puces doivent y penser, et il en va de même pour les personnes qui essaient d'écrire des logiciels système sur des ordinateurs multiprocesseurs.
La vraie question est de savoir jusqu'où ira le parallélisme sur l'échelle de l'abstraction ? Dans cent ans, cela affectera-t-il même les programmeurs d'applications ? Ou sera-t-ce quelque chose que les auteurs de compilateurs prennent en compte, mais qui est généralement invisible dans le code source des applications ?
Une chose qui semble probable, c'est que la plupart des opportunités de parallélisme seront gaspillées. C'est un cas particulier de ma prédiction plus générale selon laquelle la plupart de la puissance informatique supplémentaire que nous recevons sera gaspillée. Je m'attends à ce que, comme pour la vitesse stupéfiante du matériel sous-jacent, le parallélisme soit quelque chose qui est disponible si vous le demandez explicitement, mais qui n'est généralement pas utilisé. Cela implique que le type de parallélisme que nous aurons dans cent ans ne sera pas, sauf dans des applications spéciales, un parallélisme massif. Je m'attends à ce que, pour les programmeurs ordinaires, ce soit plus comme pouvoir bifurquer des processus qui finissent tous par s'exécuter en parallèle.
Et cela, comme demander des implémentations spécifiques de structures de données, sera quelque chose que vous ferez assez tard dans la vie d'un programme, lorsque vous essayerez de l'optimiser. Les versions 1 ignoreront généralement tous les avantages à tirer du calcul parallèle, tout comme elles ignoreront les avantages à tirer de représentations spécifiques des données.
Sauf dans des types d'applications spéciaux, le parallélisme ne permettra pas de généraliser les programmes qui seront écrits dans cent ans. Ce serait une préoptimisation si c'était le cas.
Combien de langages de programmation y aura-t-il dans cent ans ? Il semble y avoir un nombre énorme de nouveaux langages de programmation ces derniers temps. Une partie de la raison est que le matériel plus rapide a permis aux programmeurs de faire des compromis différents entre la vitesse et la commodité, en fonction de l' application. Si c'est une vraie tendance, le matériel que nous aurons dans cent ans ne devrait que l'accroître.
Et pourtant, il n'y aura peut-être que quelques langages largement utilisés dans cent ans. Une partie de la raison pour laquelle je dis cela est l'optimisme : il semble que, si vous faisiez vraiment du bon travail, vous pourriez créer un langage qui serait idéal pour écrire une version 1 lente, et pourtant, avec les bons conseils d'optimisation au compilateur, produirait également un code très rapide lorsque cela est nécessaire. Donc, comme je suis optimiste, je vais prédire que malgré l'énorme écart qu'ils auront entre l'efficacité acceptable et maximale, les programmeurs dans cent ans auront des langages qui peuvent couvrir la plupart de cet écart.
Au fur et à mesure que cet écart se creuse, les profileurs deviendront de plus en plus importants. On accorde peu d'attention au profilage aujourd'hui. Beaucoup de gens semblent encore croire que la façon d'obtenir des applications rapides est d' écrire des compilateurs qui génèrent du code rapide. Au fur et à mesure que l'écart entre les performances acceptables et maximales se creuse, il deviendra de plus en plus clair que la façon d'obtenir des applications rapides est d'avoir un bon guide de l'une à l'autre.
Lorsque je dis qu'il n'y aura peut-être que quelques langages, je n'inclue pas les "petits langages" spécifiques à un domaine. Je pense que ces langages intégrés sont une excellente idée, et je m'attends à ce qu'ils prolifèrent. Mais je m'attends à ce qu'ils soient écrits comme des peaux suffisamment fines pour que les utilisateurs puissent voir le langage général sous-jacent.
Qui concevra les langages du futur ? L'une des tendances les plus excitantes de ces dix dernières années a été l'essor des langages open source comme Perl, Python et Ruby. La conception des langages est reprise par les hackers. Les résultats sont jusqu'à présent désordonnés, mais encourageants. Il y a des idées incroyablement novatrices dans Perl, par exemple. Beaucoup sont incroyablement mauvaises, mais c'est toujours vrai pour les efforts ambitieux. À son rythme actuel de mutation, Dieu sait en quoi Perl pourrait évoluer dans cent ans.
Ce n'est pas vrai que ceux qui ne peuvent pas faire, enseignent (certains des meilleurs hackers que je connaisse sont des professeurs), mais il est vrai qu'il y a beaucoup de choses que ceux qui enseignent ne peuvent pas faire. La recherche impose des restrictions de caste contraignantes. Dans tout domaine académique, il y a des sujets sur lesquels il est acceptable de travailler et d'autres non. Malheureusement, la distinction entre les sujets acceptables et les sujets interdits est généralement basée sur la façon dont le travail semble intellectuel lorsqu'il est décrit dans des articles de recherche, plutôt que sur son importance pour obtenir de bons résultats. Le cas extrême est probablement la littérature ; les personnes qui étudient la littérature disent rarement quelque chose qui serait d'une quelconque utilité à ceux qui la produisent.
Bien que la situation soit meilleure dans les sciences, le chevauchement entre le type de travail que vous êtes autorisé à faire et le type de travail qui produit de bons langages est décourageant. (Olin Shivers s'est plaint avec éloquence à ce sujet.) Par exemple, les types semblent être une source inépuisable d'articles de recherche, malgré le fait que le typage statique semble exclure les vraies macros - sans lesquelles, à mon avis, aucun langage ne vaut la peine d'être utilisé.
La tendance n'est pas seulement vers des langages développés comme des projets open source plutôt que comme de la "recherche", mais vers des langages conçus par les programmeurs d'applications qui ont besoin de les utiliser, plutôt que par les auteurs de compilateurs. Cela semble être une bonne tendance et je m'attends à ce qu'elle se poursuive.
Contrairement à la physique dans cent ans, qui est presque nécessairement impossible à prédire, je pense qu'il pourrait être possible en principe de concevoir un langage maintenant qui plairait aux utilisateurs dans cent ans.
Une façon de concevoir un langage est d'écrire simplement le programme que vous aimeriez pouvoir écrire, sans tenir compte du fait qu'il existe un compilateur qui peut le traduire ou un matériel qui peut l'exécuter. Lorsque vous faites cela, vous pouvez supposer des ressources illimitées. Il semble que nous devrions être capables d'imaginer des ressources illimitées aussi bien aujourd'hui que dans cent ans.
Quel programme aimerait-on écrire ? Celui qui demande le moins de travail. Sauf que non : celui qui serait le moins de travail si vos idées sur la programmation n'étaient pas déjà influencées par les langages que vous utilisez actuellement. Une telle influence peut être si omniprésente qu'il faut un grand effort pour la surmonter. On pourrait penser qu'il serait évident pour des créatures aussi paresseuses que nous comment exprimer un programme avec le moins d'effort possible. En fait, nos idées sur ce qui est possible ont tendance à être si limitées par le langage dans lequel nous pensons que des formulations plus faciles de programmes semblent très surprenantes. Ce sont des choses que vous devez découvrir, et non des choses dans lesquelles vous vous enfoncez naturellement.
Une astuce utile ici est d'utiliser la longueur du programme comme une approximation de la quantité de travail qu'il faut pour l'écrire. Pas la longueur en caractères, bien sûr, mais la longueur en éléments syntaxiques distincts - en gros, la taille de l'arbre d'analyse. Il n'est peut-être pas tout à fait vrai que le programme le plus court est celui qui demande le moins de travail à écrire, mais c'est assez proche pour que vous soyez mieux de viser la cible solide de la brièveté que la cible floue et voisine du moins de travail. L'algorithme de conception des langages devient alors : regardez un programme et demandez-vous : y a-t-il un moyen d'écrire cela qui soit plus court ?
En pratique, écrire des programmes dans un langage imaginaire de cent ans fonctionnera à des degrés divers en fonction de votre proximité avec le cœur. Les routines de tri, vous pouvez les écrire maintenant. Mais ce serait difficile de prédire maintenant quels types de bibliothèques pourraient être nécessaires dans cent ans. On peut supposer que de nombreuses bibliothèques seront destinées à des domaines qui n'existent même pas encore. Si SETI@home fonctionne, par exemple, nous aurons besoin de bibliothèques pour communiquer avec les extraterrestres. À moins bien sûr qu'ils ne soient suffisamment avancés pour communiquer déjà en XML.
À l'autre extrême, je pense que vous pourriez être en mesure de concevoir le langage de base aujourd'hui. En fait, certains pourraient soutenir qu'il a déjà été conçu en grande partie en 1958.
Si le langage centenaire était disponible aujourd'hui, voudrions-nous programmer en lui ? Une façon de répondre à cette question est de regarder en arrière. Si les langages de programmation d'aujourd'hui avaient été disponibles en 1960, quelqu'un aurait-il voulu les utiliser ?
D'une certaine manière, la réponse est non. Les langages d'aujourd'hui supposent une infrastructure qui n'existait pas en 1960. Par exemple, un langage dans lequel l'indentation est significative, comme Python, ne fonctionnerait pas très bien sur les terminaux d'impression. Mais en mettant de côté ces problèmes
- en supposant, par exemple, que les programmes étaient tous simplement écrits sur papier - les programmeurs des années 1960 auraient-ils aimé écrire des programmes dans les langages que nous utilisons maintenant ?
Je pense que oui. Certains des moins imaginatifs, qui avaient des artefacts des premiers langages intégrés dans leurs idées de ce qu'était un programme, auraient peut-être eu du mal. (Comment pouvez-vous manipuler des données sans faire d'arithmétique de pointeurs ? Comment pouvez-vous implémenter des organigrammes sans gotos ?) Mais je pense que les programmeurs les plus intelligents n'auraient eu aucun mal à tirer le meilleur parti des langages d'aujourd'hui, s'ils les avaient eus.
Si nous avions le langage centenaire maintenant, il ferait au moins un excellent pseudo-code. Qu'en est-il de son utilisation pour écrire des logiciels ? Puisque le langage centenaire devra générer du code rapide pour certaines applications, on peut supposer qu'il pourrait générer du code suffisamment efficace pour s'exécuter de manière acceptable sur notre matériel. Nous devrions peut-être donner plus de conseils d'optimisation qu'aux utilisateurs dans cent ans, mais cela pourrait quand même être un gain net.
Nous avons maintenant deux idées qui, si vous les combinez, suggèrent des possibilités intéressantes : (1) le langage centenaire pourrait, en principe, être conçu aujourd'hui, et (2) un tel langage, s'il existait, pourrait être bon à programmer aujourd'hui. Lorsque vous voyez ces idées présentées de cette manière, il est difficile de ne pas penser : pourquoi ne pas essayer d'écrire le langage centenaire maintenant ?
Lorsque vous travaillez sur la conception des langages, je pense qu'il est bon d' avoir une telle cible et de la garder consciemment à l'esprit. Lorsque vous apprenez à conduire, l'un des principes qu'on vous enseigne est d' aligner la voiture non pas en alignant le capot avec les bandes peintes sur la route, mais en visant un point dans le lointain. Même si tout ce qui vous intéresse est ce qui se passe dans les dix prochains mètres, c'est la bonne réponse. Je pense que nous pouvons et devons faire la même chose avec les langages de programmation.
Remarques
Je crois que Lisp Machine Lisp a été le premier langage à incarner le principe selon lequel les déclarations (à l'exception de celles des variables dynamiques) n'étaient que des conseils d'optimisation, et ne changeraient pas la signification d'un programme correct. Common Lisp semble avoir été le premier à l'affirmer explicitement.
Merci à Trevor Blackwell, Robert Morris et Dan Giffin pour avoir lu les brouillons de ce texte, et à Guido van Rossum, Jeremy Hylton et le reste de l'équipe Python pour m'avoir invité à parler à PyCon.