Loading...

LA LANGUE CENTENAIRE

Original

Avril 2003

(Cet essai est tiré d’un discours prononcé à PyCon 2003.)

Il est difficile de prédire à quoi ressemblera la vie dans cent ans. Nous ne pouvons affirmer avec certitude que peu de choses. Nous savons que tout le monde conduira des voitures volantes, que les lois de zonage seront assouplies pour autoriser la construction d'immeubles de plusieurs centaines d'étages, qu'il fera sombre la plupart du temps et que les femmes seront toutes entraînées aux arts martiaux. Je voudrais ici m'attarder sur un détail de cette image. Quel type de langage de programmation utiliseront-ils pour écrire le logiciel qui contrôlera ces voitures volantes ?

Cela vaut la peine d'y réfléchir, non pas tant parce que nous allons réellement pouvoir utiliser ces langues, mais parce que, si nous avons de la chance, nous les utiliserons sur le chemin qui mène de tel point à tel autre.

Je pense que, comme les espèces, les langues formeront des arbres évolutifs, avec des ramifications en cul-de-sac un peu partout. Nous pouvons déjà voir cela se produire. Le COBOL, malgré sa popularité, ne semble pas avoir de descendants intellectuels. C'est une impasse évolutive, une langue néandertalienne.

Je prédis un destin similaire pour Java. On m'envoie parfois des courriers en me disant : « Comment pouvez-vous dire que Java ne deviendra pas un langage à succès ? C'est déjà un langage à succès. » Et je reconnais que c'est le cas, si l'on mesure le succès à l'espace occupé par les livres sur le sujet (en particulier les livres individuels), ou au nombre d'étudiants qui croient qu'ils doivent l'apprendre pour obtenir un emploi. Quand je dis que Java ne deviendra pas un langage à succès, je veux dire quelque chose de plus précis : que Java deviendra 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 pour laquelle nous posons 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 proche des branches principales est une heuristique utile pour trouver des langages dans lesquels il sera bon de programmer maintenant.

À tout moment, vous êtes probablement plus heureux sur les branches principales d'un arbre évolutif. Même lorsqu'il y avait encore beaucoup de Néandertaliens, ça devait être pénible d'en être un. Les Cro-Magnons venaient constamment vous frapper et voler votre nourriture.

La raison pour laquelle je veux savoir à quoi ressembleront les langues dans cent ans, c'est pour savoir sur quelle branche de l'arbre parier maintenant.

L'évolution des langues diffère de celle des espèces car les ramifications peuvent converger. La branche Fortran, par exemple, semble fusionner avec les descendants d'Algol. En théorie, c'est également possible pour les espèces, mais il est peu probable que cela se soit produit pour des organismes plus grands qu'une cellule.

La convergence est plus probable pour les langues, en partie parce que l'espace des possibilités est plus restreint et en partie parce que les mutations ne sont pas aléatoires. Les concepteurs de langues intègrent délibérément des idées d'autres langues.

Il est particulièrement utile pour les concepteurs de langages de réfléchir à l'évolution probable des langages de programmation, 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. Cela devient une heuristique pour prendre les bonnes décisions en matière de conception de langage.

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 pour la survie à long terme d'une langue. Le reste, vous pouvez le modifier. C'est comme la règle selon laquelle, lors de l'achat d'une maison, vous devez d'abord tenir compte de l'emplacement. Tout le reste, vous pouvez le régler plus tard, mais vous ne pouvez pas régler l'emplacement.

Je pense qu'il est important non seulement que les axiomes soient bien choisis, mais qu'ils soient peu nombreux. Les mathématiciens ont toujours eu ce sentiment à propos des axiomes : moins il y en a, mieux c'est, et je pense qu'ils ont raison.

Il faut au moins que l'on s'intéresse de près au cœur d'un langage pour voir s'il y a des axiomes qui pourraient être éliminés. J'ai constaté au cours de ma longue carrière de plouc que la saleté engendre la saleté, et j'ai vu cela se produire dans les logiciels ainsi que sous les lits et dans les coins des pièces.

J'ai l'impression que les principales branches de l'arbre évolutif passent par les langues qui ont les noyaux les plus petits et les plus propres. Plus une langue est capable d'écrire en elle-même, mieux c'est.

Bien sûr, je fais une hypothèse assez ambitieuse en demandant à quoi ressembleront les langages de programmation dans cent ans. Est-ce que nous écrirons des programmes dans cent ans ? N'allons-nous pas simplement dire aux ordinateurs ce que nous voulons qu'ils fassent ?

Jusqu'à présent, les progrès dans ce domaine sont restés limités. Je pense que dans cent ans, les gens continueront à dire aux ordinateurs ce qu'ils doivent faire en utilisant des programmes que nous reconnaîtrons comme tels. Il y a peut-être des tâches que nous résolvons aujourd'hui en écrivant des programmes et pour lesquelles, dans cent ans, nous n'aurons plus besoin d'écrire de programmes, mais je pense qu'il y aura encore beaucoup de programmation du type que nous faisons aujourd'hui.

Il peut paraître présomptueux de penser que quiconque puisse prédire à quoi ressemblera une technologie dans cent ans. Mais n’oublions pas que nous avons déjà presque cinquante ans d’histoire derrière nous. Se projeter dans cent ans est une idée compréhensible quand on considère la lenteur avec laquelle les langues ont évolué au cours des cinquante dernières années.

Les langages évoluent lentement car 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. Le rythme d'évolution des langages de programmation ressemble donc davantage à celui de la notation mathématique qu'à celui des transports ou des communications, par exemple. La notation mathématique évolue, mais pas à la vitesse de l'éclair que l'on observe dans le domaine technologique.

Peu importe les composants dont seront constitués les ordinateurs dans cent ans, on peut prédire qu'ils seront bien plus rapides qu'aujourd'hui. Si la loi de Moore continue à s'appliquer, ils seront 74 quintillions (73 786 976 294 838 206 464) de fois plus rapides. C'est assez difficile à imaginer. Et en effet, la prédiction la plus probable en matière de vitesse est 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 à un moment ou à un autre. Mais je n'ai aucun mal à croire que les ordinateurs seront bien plus rapides. Même s'ils ne finissent par être qu'un million de fois plus rapides, cela devrait changer considérablement les règles de base des langages de programmation. Entre autres choses, il y aura plus de place pour ce que l'on considère aujourd'hui comme des langages lents, c'est-à-dire des langages qui ne produisent pas de code très efficace.

Et pourtant, certaines applications exigeront toujours de la vitesse. Certains des problèmes que nous souhaitons résoudre avec des ordinateurs sont créés par des ordinateurs ; par exemple, la vitesse à laquelle vous devez traiter des images vidéo dépend de la vitesse à laquelle un autre ordinateur peut les générer. Et il existe une autre catégorie de problèmes qui ont par nature une capacité illimitée à absorber des 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 devront couvrir une gamme de performances toujours plus large. Nous avons déjà vu cela se produire. Les implémentations actuelles de certains nouveaux langages populaires sont scandaleusement inefficaces par rapport aux normes des décennies précédentes.

Ce phénomène ne se limite pas aux langages de programmation. Il s’agit d’une tendance générale de l’histoire. À 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. Il y a trente ans, les gens auraient été étonnés de la désinvolture avec laquelle nous passons des appels longue distance. Il y a cent ans, les gens auraient été encore plus étonnés qu’un jour un colis puisse 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 offrir dans les cent prochaines années. Ils seront presque tous gaspillés.

J'ai appris à programmer quand la puissance des ordinateurs était limitée. Je me souviens avoir supprimé tous les espaces de mes programmes Basic pour qu'ils puissent tenir dans la mémoire d'un TRS-80 4K. L'idée que tous ces logiciels incroyablement inefficaces brûlent des cycles en faisant la même chose encore et encore me semble plutôt dégoûtante. Mais je pense que mes intuitions sont fausses. Je suis comme quelqu'un qui a grandi dans la pauvreté et qui ne supporte pas de dépenser de l'argent même pour quelque chose d'important, comme aller chez le médecin.

Certains types de déchets sont vraiment dégoûtants. Les SUV, par exemple, seraient sans doute dégoûtants même s'ils fonctionnaient avec un carburant qui ne s'épuiserait jamais et ne générerait aucune pollution. Les SUV sont dégoûtants parce qu'ils sont la solution à un problème dégoûtant. (Comment rendre les minivans plus masculins.) Mais tous les déchets ne sont pas mauvais. Maintenant que nous avons l'infrastructure pour les supporter, compter les minutes de vos appels longue distance commence à vous sembler fastidieux. Si vous avez les ressources, il est plus élégant de considérer tous les appels téléphoniques comme une seule sorte de chose, peu importe où se trouve l'interlocuteur.

Il existe des gaspillages bénéfiques et des gaspillages néfastes. Je m'intéresse aux gaspillages bénéfiques, ceux qui, en dépensant plus, nous permettent d'obtenir des conceptions plus simples. Comment allons-nous tirer parti des possibilités de gaspillage que nous offriront les nouveaux matériels plus rapides ?

Le désir de vitesse est si profondément ancré en nous, avec nos ordinateurs de petite taille, qu'il faudra un effort conscient pour le surmonter. Dans la conception du langage, nous devrions rechercher consciemment des situations où nous pouvons échanger l'efficacité contre la plus petite augmentation de confort.

La plupart des structures de données existent pour des raisons de rapidité. Par exemple, de nombreux langages utilisent aujourd'hui à la fois des chaînes et des listes. Sémantiquement, les chaînes sont plus ou moins un sous-ensemble de listes dont les éléments sont des caractères. Alors pourquoi avez-vous besoin d'un type de données distinct ? Non, vraiment. Les chaînes n'existent que pour l'efficacité. Mais il est inutile d'encombrer la sémantique du langage avec des hacks pour accélérer l'exécution des programmes. Avoir des chaînes dans un langage semble être un cas d'optimisation prématurée.

Si l'on considère le cœur d'une langue comme un ensemble d'axiomes, il est certainement dégueulasse d'ajouter des axiomes supplémentaires qui n'ajoutent aucun pouvoir expressif, 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 meilleure façon de résoudre ce problème, je pense, est de séparer le sens d'un programme des détails de sa mise en œuvre. Au lieu d'avoir à la fois des listes et des chaînes, utilisez simplement des listes, avec un moyen de donner au compilateur des conseils d'optimisation qui lui permettront de disposer les chaînes sous forme d'octets contigus si nécessaire.

Étant donné que la vitesse n'a pas d'importance dans la plupart des programmes, vous n'aurez généralement pas besoin de vous soucier de ce type de microgestion. Cela sera de plus en plus vrai à mesure que les ordinateurs deviendront plus rapides.

En parlant moins de mise en œuvre, les programmes devraient également gagner en flexibilité. Les spécifications changent au cours de l'écriture d'un programme, ce qui est non seulement inévitable, mais souhaitable.

Le mot « essai » vient du verbe français « essayer ». Un essai, au sens original, est quelque chose que vous écrivez pour essayer de comprendre quelque chose. Cela se produit également dans les logiciels. Je pense que certains des meilleurs programmes étaient des essais, dans le sens où les auteurs ne savaient pas exactement au début ce qu'ils essayaient d'écrire.

Les hackers Lisp connaissent déjà l'intérêt 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 si 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 nécessite un effort conscient pour ne pas penser à sa provenance.

Dans cent ans, les programmeurs chercheront avant tout un langage qui leur permettra de créer une version 1 incroyablement inefficace d'un programme avec le moins d'efforts possible. Du moins, c'est ainsi que nous le décririons aujourd'hui. Ils diront qu'ils veulent un langage dans lequel il est facile de programmer.

Un logiciel inefficace n'est pas dégoûtant. Ce qui est dégoûtant, c'est un langage qui oblige les programmeurs à faire un travail inutile. La véritable inefficacité est la perte de temps des programmeurs, et non la perte de temps des machines. Cela deviendra de plus en plus évident à mesure que les ordinateurs deviendront plus rapides.

Je pense que se débarrasser des chaînes de caractères est déjà une chose à laquelle nous pourrions penser. Nous l'avons fait dans Arc et cela semble être une victoire ; certaines opérations qui seraient difficiles à décrire comme des expressions régulières peuvent être facilement décrites comme des fonctions récursives.

Jusqu'où ira cet aplatissement des structures de données ? Je peux imaginer des possibilités qui me choquent même, avec mon esprit consciencieusement élargi. Allons-nous nous débarrasser des tableaux, par exemple ? Après tout, ils ne sont qu'un sous-ensemble de tables de hachage où les clés sont des vecteurs d'entiers. Allons-nous remplacer les tables de hachage elles-mêmes par des listes ?

Il existe des perspectives encore plus choquantes. Le Lisp décrit par McCarthy en 1960, par exemple, ne comportait pas de nombres. Logiquement, il n'est pas nécessaire d'avoir une notion distincte des nombres, car on peut les représenter sous forme de listes : l'entier n pourrait être représenté sous forme de liste de n éléments. On peut faire des mathématiques de cette façon. C'est juste insupportablement inefficace.

Personne n'a réellement proposé d'implémenter les nombres sous forme de listes dans la pratique. En fait, l'article de McCarthy de 1960 n'était pas du tout destiné à être implémenté à l'époque. Il s'agissait d'un exercice théorique , d'une tentative de créer une alternative plus élégante à la machine de Turing. Lorsque quelqu'un a pris, de manière inattendue, cet article et l'a traduit en un interpréteur Lisp fonctionnel, les nombres n'étaient certainement pas représentés sous forme de listes ; ils étaient 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 moins comme une question sérieuse que comme une façon de jouer 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 grandes. Je ne vois pas pourquoi pas. L'avenir est assez long. S'il y a quelque chose que nous pouvons faire pour diminuer le nombre d'axiomes dans le langage de base, cela semble être le côté sur lequel il faut parier lorsque t approche de l'infini. Si l'idée semble toujours insupportable dans cent ans, peut-être qu'elle ne le sera 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 sur l'implémentation, soit défini de cette manière. En pratique, tout programme qui voudrait faire un peu de 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 réduire les cycles est d’avoir plusieurs couches de logiciel entre l’application et le matériel. C’est aussi une tendance que nous observons déjà : de nombreux langages récents sont compilés en byte code. Bill Woods m’a dit un jour qu’en règle générale, chaque couche d’interprétation coûte un facteur 10 en vitesse. Ce coût supplémentaire vous permet d’acquérir de la flexibilité.

La toute première version d'Arc était un cas extrême de ce type de lenteur à plusieurs niveaux, avec les avantages correspondants. C'était un interpréteur « métacirculaire » classique écrit sur Common Lisp, avec une ressemblance familiale certaine avec la fonction eval définie dans l'article original de McCarthy sur Lisp. L'ensemble ne comprenait que quelques centaines de lignes de code, il était donc très facile à comprendre et à modifier. Le Common Lisp que nous utilisions, CLisp, lui-même s'exécutait sur un interpréteur de byte code. Nous avions donc ici deux niveaux d'interprétation, l'un d'eux (le premier) étant étonnamment inefficace, et le langage était utilisable. A peine utilisable, je l'admets, mais utilisable.

L'écriture de logiciels sous forme de couches multiples est une technique puissante, même au sein d'applications. La programmation ascendante consiste à écrire un programme sous forme d'une série de couches, chacune servant de langage pour la couche supérieure. Cette approche tend à produire des programmes plus petits et plus flexibles. C'est également la meilleure voie vers ce Saint Graal, la réutilisabilité. Un langage est par définition réutilisable. Plus vous pouvez insérer de 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 preuve du contraire ne semble pouvoir l'en défaire. Mais même si certains logiciels orientés objet sont réutilisables, ce qui les rend réutilisables est leur caractère ascendant, et non leur orientation objet. Prenons l'exemple des bibliothèques : elles sont réutilisables parce qu'elles sont un langage, 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. Même si 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 permet d'accumuler des programmes sous forme d'une série de correctifs.

Les grandes organisations ont toujours tendance à développer leurs logiciels de cette manière, et je m’attends à ce que cela soit aussi vrai dans cent ans qu’aujourd’hui.

Tant qu'on parle du futur, il vaut mieux parler du calcul parallèle, car c'est là que cette idée semble se développer. En d'autres termes, quel que soit le moment où l'on parle, le calcul parallèle semble être quelque chose qui va se produire dans le futur.

L'avenir nous rattrapera-t-il un jour ? On parle du calcul parallèle comme d'un phénomène imminent depuis au moins 20 ans, et cela n'a pas eu beaucoup d'impact sur la pratique de la programmation jusqu'à présent. Ou pas ? Les concepteurs de puces doivent déjà y réfléchir, tout comme les personnes qui essaient d'écrire des logiciels système sur des ordinateurs multi-processeurs.

La vraie question est de savoir jusqu'où ira le parallélisme dans l'échelle de l'abstraction. Dans cent ans, affectera-t-il même les programmeurs d'applications ? Ou s'agira-t-il d'un élément auquel réfléchiront les auteurs de compilateurs, mais qui sera généralement invisible dans le code source des applications ?

Il semble probable 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 majeure partie de la puissance informatique supplémentaire dont nous disposons 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 soit disponible si vous le demandez explicitement, mais qui ne soit 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 plutôt comme la possibilité de créer 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 tenterez de l'optimiser. Les versions 1 ignoreront généralement tous les avantages que l'on peut tirer du calcul parallèle, tout comme elles ignoreront les avantages que l'on peut tirer de représentations spécifiques de données.

Sauf dans certains types d'applications particuliers, le parallélisme ne s'imposera pas dans les programmes qui seront écrits dans cent ans. Ce serait une optimisation prématurée si c'était le cas.

Combien de langages de programmation existera-t-il dans cent ans ? Il semble qu'un nombre considérable de nouveaux langages de programmation soient apparus ces derniers temps. Cela s'explique en partie par le fait que des matériels plus rapides ont permis aux programmeurs de faire différents compromis entre vitesse et commodité, en fonction de l'application. Si cette tendance est réelle, le matériel dont nous disposerons dans cent ans ne devrait qu'augmenter.

Et pourtant, il se peut que dans cent ans, il n'y ait plus que quelques langages largement utilisés. Je dis cela en partie par optimisme : il semble que, si vous faites un très bon travail, vous pourriez créer un langage idéal pour écrire une version 1 lente, et pourtant, avec les bons conseils d'optimisation au compilateur, il produirait également du code très rapide si nécessaire. Donc, comme je suis optimiste, je vais prédire que malgré l'énorme écart entre l'efficacité acceptable et l'efficacité maximale, les programmeurs d'ici cent ans disposeront de langages capables de couvrir la majeure partie de ces tâches.

À mesure que cet écart se creuse, les profileurs deviendront de plus en plus importants. On accorde peu d’attention au profilage à l’heure actuelle. Beaucoup de gens semblent encore croire que le moyen d’obtenir des applications rapides est d’écrire des compilateurs qui génèrent du code rapide. À mesure que l’écart entre les performances acceptables et maximales se creuse, il deviendra de plus en plus évident que le moyen d’obtenir des applications rapides est d’avoir un bon guide pour passer de l’une à l’autre.

Quand je dis qu'il n'y aura peut-être que quelques langages, je n'inclus pas les « petits langages » spécifiques à un domaine. Je pense que de tels 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 couches suffisamment fines pour que les utilisateurs puissent voir le langage à usage général en dessous.

Qui concevra les langages du futur ? L'une des tendances les plus passionnantes 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 en train d'être reprise en main par les hackers. Les résultats obtenus jusqu'à présent sont confus, mais encourageants. Perl contient par exemple des idées étonnamment novatrices. Beaucoup sont étonnamment mauvaises, mais c'est toujours le cas pour les efforts ambitieux. Au rythme actuel de mutation, Dieu sait en quoi Perl pourrait évoluer dans cent ans.

Il n’est pas vrai que ceux qui ne savent 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 castes contraignantes. Dans tout domaine universitaire, il y a des sujets sur lesquels il est acceptable de travailler et d’autres qui ne le sont pas. Malheureusement, la distinction entre les sujets acceptables et interdits repose généralement sur le caractère intellectuel du travail lorsqu’il est décrit dans les 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 quoi que ce soit qui puisse être d’une quelconque utilité à ceux qui la produisent.

Bien que la situation soit meilleure dans le domaine scientifique, le chevauchement entre le type de travail que vous êtes autorisé à faire et le type de travail qui produit de bons langages est désespérément faible. (Olin Shivers s'en est plaint avec éloquence.) 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 à ce que les langages soient développés en tant que projets open source plutôt que dans le cadre de la « recherche », mais à ce que les langages soient 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 à ce qui se passera en physique dans cent ans, ce qui est presque nécessairement impossible à prévoir, je pense qu’il est possible en principe de concevoir aujourd’hui un langage qui pourrait intéresser les utilisateurs dans cent ans.

Une façon de concevoir un langage consiste à écrire le programme que vous souhaitez pouvoir écrire, sans tenir compte du fait qu'il existe un compilateur capable de le traduire ou un matériel capable de l'exécuter. En procédant ainsi, vous pouvez supposer que les ressources sont illimitées. Il semble que nous devrions pouvoir 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. Mais pas tout à fait : celui qui demande le moins de travail si nos idées sur la programmation n'étaient pas déjà influencées par les langages auxquels nous sommes habitués. 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 de savoir comment exprimer un programme avec le moins d'effort possible. En fait, nos idées sur ce qui est possible ont tendance à être tellement limitées par le langage dans lequel nous pensons que des formulations de programmes plus simples semblent très surprenantes. C'est quelque chose que vous devez découvrir, pas quelque chose dans lequel vous vous enfoncez naturellement.

Une astuce utile ici est d'utiliser la longueur du programme comme une approximation de la quantité de travail à é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 suffisamment proche pour que vous ayez intérêt à viser l'objectif solide de la concision plutôt que celui flou et proche du moindre travail. L'algorithme de conception du langage devient alors : regardez un programme et demandez-vous s'il existe un moyen d'écrire cela de manière plus courte ?

En pratique, l'écriture de programmes dans un langage centenaire imaginaire fonctionnera à des degrés divers en fonction de votre proximité avec le noyau. Vous pouvez écrire des routines de tri dès maintenant. Mais il serait difficile de prédire aujourd'hui quels types de bibliothèques seront nécessaires dans cent ans. Il est probable 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 l’on pourrait concevoir le langage de base aujourd’hui. En fait, certains pourraient affirmer qu’il a déjà été en grande partie conçu en 1958.

Si le langage centenaire était disponible aujourd’hui, aurions-nous voulu programmer avec ? Une façon de répondre à cette question est de regarder en arrière. Si les langages de programmation actuels avaient été disponibles en 1960, est-ce que quelqu’un aurait voulu les utiliser ?

D'une certaine manière, la réponse est non. Les langages d'aujourd'hui reposent sur une infrastructure qui n'existait pas en 1960. Par exemple, un langage dans lequel l'indentation est importante, comme Python, ne fonctionnerait pas très bien sur des terminaux d'imprimante. Mais en laissant de côté ces problèmes (en supposant, par exemple, que tous les programmes étaient simplement écrits sur papier), les programmeurs des années 1960 auraient-ils aimé écrire des programmes dans les langages que nous utilisons aujourd'hui ?

Je pense que oui. Certains des programmeurs les moins imaginatifs, qui avaient intégré des artefacts des premiers langages dans leur conception de ce qu'était un programme, ont peut-être eu des difficultés. (Comment peut-on manipuler des données sans faire de l'arithmétique de pointeurs ? Comment peut-on implémenter des organigrammes sans gotos ?) Mais je pense que les programmeurs les plus intelligents n'auraient eu aucune difficulté à tirer le meilleur parti des langages actuels, s'ils en avaient eu.

Si nous disposions aujourd'hui du langage centenaire, il constituerait au moins un excellent pseudo-code. Pourquoi ne pas l'utiliser pour écrire des logiciels ? Étant donné que le langage centenaire devra générer du code rapide pour certaines applications, il pourrait vraisemblablement générer du code suffisamment efficace pour fonctionner de manière acceptable sur notre matériel. Nous devrons peut-être donner plus de conseils d'optimisation que les utilisateurs dans cent ans, mais cela pourrait quand même être une victoire nette.

Nous avons maintenant deux idées qui, si on les combine, 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 intéressant à utiliser pour 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 d'un langage, je pense qu'il est bon d'avoir un tel objectif et de le 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 au loin. Même si tout ce qui vous intéresse est ce qui se passe dans les dix mètres qui suivent, c'est la bonne réponse. Je pense que nous pouvons et devrions 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 changeaient pas le sens d'un programme correct. Common Lisp semble avoir été le premier à l'énoncer explicitement.

Merci à Trevor Blackwell, Robert Morris et Dan Giffin pour avoir lu les brouillons de ce document, ainsi qu'à Guido van Rossum, Jeremy Hylton et au reste de l'équipe Python pour m'avoir invité à prendre la parole à PyCon.