CINQ QUESTIONS SUR LA CONCEPTION DU LANGAGE
OriginalMai 2001
(Voici quelques notes que j'ai prises pour une table ronde sur la conception du langage de programmation au MIT le 10 mai 2001.)
1. Les langages de programmation sont destinés aux personnes.
Les langages de programmation sont la façon dont les gens communiquent avec les ordinateurs. L'ordinateur serait tout aussi heureux de parler n'importe quel langage sans ambiguïté. La raison pour laquelle nous avons des langages de haut niveau est que les gens ne peuvent pas gérer le langage machine. Le but des langages de programmation est d'empêcher nos pauvres cerveaux humains fragiles d'être submergés par une masse de détails.
Les architectes savent que certains types de problèmes de conception sont plus personnels que d’autres. L’un des problèmes de conception les plus simples et les plus abstraits est la conception de ponts. Dans ce cas, votre travail consiste essentiellement à couvrir une distance donnée avec le moins de matériaux possible. L’autre extrémité du spectre est la conception de chaises. Les concepteurs de chaises doivent passer leur temps à penser aux fesses des humains.
Les logiciels sont également différents. Concevoir des algorithmes pour acheminer des données sur un réseau est un problème abstrait et agréable, comme concevoir des ponts. Concevoir des langages de programmation, c'est comme concevoir des chaises : il s'agit de gérer les faiblesses humaines.
La plupart d’entre nous détestent le reconnaître. Concevoir des systèmes d’une grande élégance mathématique semble beaucoup plus attrayant pour la plupart d’entre nous que de céder aux faiblesses humaines. Et l’élégance mathématique a un rôle à jouer : certains types d’élégance rendent les programmes plus faciles à comprendre. Mais l’élégance n’est pas une fin en soi.
Et quand je dis que les langages doivent être conçus pour s'adapter aux faiblesses humaines, je ne veux pas dire que les langages doivent être conçus pour les mauvais programmeurs. En fait, je pense qu'il faut concevoir pour les meilleurs programmeurs , mais même les meilleurs programmeurs ont des limites. Je ne pense pas que quiconque aimerait programmer dans un langage où toutes les variables seraient la lettre x avec des indices entiers.
2. Concevez pour vous-même et vos amis.
Si vous regardez l'histoire des langages de programmation, beaucoup des meilleurs étaient des langages conçus pour être utilisés par leurs propres auteurs, et beaucoup des pires étaient conçus pour être utilisés par d'autres personnes.
Lorsque des langages sont conçus pour d'autres personnes, il s'agit toujours d'un groupe spécifique d'autres personnes : des personnes qui ne sont pas aussi intelligentes que le concepteur du langage. Vous obtenez donc un langage qui vous parle de haut. Cobol est le cas le plus extrême, mais de nombreux langages sont imprégnés de cet esprit.
Cela n'a rien à voir avec le caractère abstrait du langage. Le C est un langage de bas niveau, mais il a été conçu pour être utilisé par ses auteurs, et c'est pourquoi les hackers l'apprécient.
L'argument en faveur de la conception de langages pour les mauvais programmeurs est qu'il y a plus de mauvais programmeurs que de bons programmeurs. C'est peut-être vrai. Mais ces quelques bons programmeurs écrivent un pourcentage disproportionné de logiciels.
Je m'intéresse à la question : comment concevoir un langage qui plaira aux meilleurs hackers ? Je pense que c'est identique à la question : comment concevoir un bon langage de programmation ?, mais même si ce n'est pas le cas, c'est au moins une question intéressante.
3. Donnez au programmeur autant de contrôle que possible.
De nombreux langages (surtout ceux conçus pour d'autres personnes) ont une attitude de gouvernante : ils essaient de vous empêcher de faire des choses qu'ils pensent ne pas être bonnes pour vous. J'aime l'approche opposée : donner au programmeur autant de contrôle que possible.
Quand j'ai commencé à apprendre Lisp, ce qui m'a le plus plu, c'est qu'il me considérait comme un partenaire à part entière. Dans les autres langages que j'avais appris jusqu'alors, il y avait le langage et mon programme, écrit dans le langage, et les deux étaient très distincts. Mais dans Lisp, les fonctions et les macros que j'écrivais étaient exactement comme celles qui constituaient le langage lui-même. Je pouvais réécrire le langage si je le voulais. Il avait le même attrait que les logiciels open source.
4. Visez la concision.
La concision est sous-estimée, voire méprisée. Mais si vous regardez dans le cœur des hackers, vous verrez qu'ils l'adorent vraiment. Combien de fois avez-vous entendu des hackers parler avec affection de la façon dont, par exemple, dans APL, ils pouvaient faire des choses incroyables avec seulement quelques lignes de code ? Je pense que tout ce que les gens vraiment intelligents aiment vraiment mérite qu'on leur prête attention.
Je pense que presque tout ce que vous pouvez faire pour raccourcir les programmes est une bonne chose. Il devrait y avoir beaucoup de fonctions de bibliothèque ; tout ce qui peut être implicite devrait l'être ; la syntaxe devrait être concise à l'extrême ; même les noms des choses devraient être courts.
Et ce ne sont pas seulement les programmes qui doivent être courts. Le manuel doit lui aussi être concis. Une bonne partie des manuels est consacrée à des éclaircissements, des réserves, des avertissements et des cas particuliers. Si vous vous forcez à raccourcir le manuel, dans le meilleur des cas, vous le faites en corrigeant les éléments de la langue qui ont nécessité tant d'explications.
5. Admettez ce qu’est le piratage informatique.
Beaucoup de gens aimeraient que le hacking soit une discipline mathématique, ou au moins une sorte de science naturelle. Je pense que le hacking ressemble davantage à l'architecture. L'architecture est liée à la physique, dans le sens où les architectes doivent concevoir des bâtiments qui ne s'effondrent pas, mais le véritable objectif des architectes est de construire de grands bâtiments, pas de faire des découvertes sur la statique.
Les hackers aiment créer des programmes de qualité. Et je pense que nous devons nous rappeler, du moins dans notre esprit, que c'est une chose admirable d'écrire de bons programmes, même si ce travail ne se traduit pas facilement dans la littérature intellectuelle conventionnelle des articles de recherche. Intellectuellement, il est tout aussi intéressant de concevoir un langage que les programmeurs adoreront que de concevoir un langage horrible qui incarne une idée sur laquelle vous pourrez publier un article.
1. Comment organiser les grandes bibliothèques ?
Les bibliothèques deviennent un élément de plus en plus important des langages de programmation. Elles deviennent également plus grandes, ce qui peut être dangereux. S'il faut plus de temps pour trouver la fonction de bibliothèque qui fera ce que vous voulez que pour l'écrire vous-même, alors tout ce code ne fait rien d'autre qu'épaissir votre manuel. (Les manuels Symbolics en sont un exemple.) Je pense donc que nous devrons travailler sur des moyens d'organiser les bibliothèques. L'idéal serait de les concevoir de manière à ce que le programmeur puisse deviner quel appel de bibliothèque fera la bonne chose.
2. Les gens ont-ils vraiment peur de la syntaxe des préfixes ?
Il s'agit d'un problème ouvert dans le sens où je m'y interroge depuis des années et je ne connais toujours pas la réponse. La syntaxe des préfixes me semble parfaitement naturelle, sauf peut-être pour les mathématiques. Mais il se pourrait qu'une grande partie de l'impopularité de Lisp soit simplement due à une syntaxe peu familière. S'il faut faire quelque chose à ce sujet, si c'est vrai, c'est une autre question.
3. De quoi avez-vous besoin pour un logiciel basé sur un serveur ?
Je pense que la plupart des applications les plus intéressantes qui seront écrites dans les vingt prochaines années seront des applications Web, c'est-à-dire des programmes qui se trouvent sur le serveur et qui communiquent avec vous via un navigateur Web. Et pour écrire ce genre de programmes, nous aurons peut-être besoin de nouvelles choses.
Nous aurons besoin d'un support pour la nouvelle façon dont les applications basées sur serveur sont publiées. Au lieu d'avoir une ou deux grosses versions par an, comme les logiciels de bureau, les applications basées sur serveur sont publiées sous forme d'une série de petites modifications. Vous pouvez avoir jusqu'à cinq ou dix versions par jour. Et en règle générale, tout le monde utilisera toujours la dernière version.
Vous savez comment concevoir des programmes qui soient débogables ? Eh bien, les logiciels basés sur un serveur doivent également être conçus pour être modifiables. Vous devez pouvoir les modifier facilement, ou au moins savoir distinguer un changement mineur d'un changement majeur.
Une autre chose qui pourrait s'avérer utile pour les logiciels basés sur serveur, étonnamment, est les continuations. Dans les logiciels basés sur le Web, vous pouvez utiliser quelque chose comme le style de passage de continuation pour obtenir l'effet des sous-routines dans le monde intrinsèquement sans état d'une session Web. Il serait peut-être intéressant d'avoir de véritables continuations, si ce n'était pas trop cher.
4. Quelles nouvelles abstractions restent à découvrir ?
Je ne sais pas si c'est un espoir raisonnable, mais une chose que j'aimerais vraiment faire, personnellement, c'est découvrir une nouvelle abstraction - quelque chose qui ferait autant de différence que d'avoir des fonctions de première classe ou la récursivité ou même des paramètres de mots-clés. C'est peut-être un rêve impossible. Ces choses ne sont pas découvertes si souvent. Mais je suis toujours à la recherche.
1. Vous pouvez utiliser la langue de votre choix.
Autrefois, écrire des programmes d'application signifiait écrire des logiciels de bureau. Or, dans ce domaine, il existe une forte tendance à écrire l'application dans le même langage que le système d'exploitation. Il y a dix ans, écrire des logiciels signifiait donc écrire des logiciels en C. Une tradition s'est finalement développée : les programmes d'application ne doivent pas être écrits dans des langages inhabituels. Et cette tradition a mis si longtemps à se développer que des personnes non techniques comme les managers et les investisseurs en capital-risque l'ont également apprise.
Les logiciels basés sur serveur font voler en éclats tout ce modèle. Avec les logiciels basés sur serveur, vous pouvez utiliser n'importe quel langage que vous voulez. Presque personne ne le comprend encore (surtout pas les managers et les investisseurs en capital-risque). Quelques hackers le comprennent, et c'est pourquoi nous entendons même parler de nouveaux langages indépendants comme Perl et Python. Nous n'entendons pas parler de Perl et de Python parce que les gens les utilisent pour écrire des applications Windows.
Ce que cela signifie pour nous, en tant que personnes intéressées par la conception de langages de programmation, c'est qu'il existe désormais potentiellement un public réel pour notre travail.
2. La vitesse vient des profileurs.
Les concepteurs de langages, ou du moins les implémenteurs de langages, aiment écrire des compilateurs qui génèrent du code rapide. Mais je ne pense pas que ce soit ce qui rend les langages rapides pour les utilisateurs. Knuth a souligné il y a longtemps que la vitesse n'a d'importance que dans quelques goulots d'étranglement critiques. Et quiconque l'a essayé sait qu'il est impossible de deviner où se trouvent ces goulots d'étranglement. Les profileurs sont la solution.
Les concepteurs de langages résolvent le mauvais problème. Les utilisateurs n'ont pas besoin de tests de performance pour être rapides. Ce dont ils ont besoin, c'est d'un langage capable de leur montrer quelles parties de leurs propres programmes doivent être réécrites. C'est de là que vient la vitesse dans la pratique. Il serait donc peut-être bénéfique que les développeurs de langages prennent la moitié du temps qu'ils auraient passé à optimiser le compilateur et le consacrent à écrire un bon profileur à la place.
3. Vous avez besoin d’une application pour piloter la conception d’un langage.
Ce n'est peut-être pas une règle absolue, mais il semble que les meilleurs langages aient tous évolué en même temps que les applications qu'ils servaient à écrire. Le langage C a été écrit par des gens qui en avaient besoin pour la programmation système. Lisp a été développé en partie pour faire de la différenciation symbolique, et McCarthy était si impatient de s'y mettre qu'il écrivait des programmes de différenciation dès le premier article sur Lisp, en 1960.
C'est particulièrement intéressant si votre application résout un nouveau problème. Cela aura tendance à amener votre langage à proposer de nouvelles fonctionnalités dont les programmeurs ont besoin. Personnellement, je suis intéressé par l'écriture d'un langage qui sera adapté à l'écriture d'applications basées sur un serveur.
[Au cours du panel, Guy Steele a également fait valoir ce point, avec la suggestion supplémentaire que l'application ne devrait pas consister à écrire le compilateur pour votre langage, à moins que votre langage ne soit destiné à l'écriture de compilateurs.]
4. Un langage doit être adapté à l’écriture de programmes jetables.
Vous savez ce qu'est un programme jetable : quelque chose que vous écrivez rapidement pour une tâche limitée. Je pense que si vous regardez autour de vous, vous constaterez que beaucoup de gros programmes sérieux ont commencé comme des programmes jetables. Je ne serais pas surpris si la plupart des programmes avaient commencé comme des programmes jetables. Et donc si vous voulez créer un langage qui soit bon pour l'écriture de logiciels en général, il doit être bon pour l'écriture de programmes jetables, car c'est le stade larvaire de la plupart des logiciels.
5. La syntaxe est liée à la sémantique.
Il est courant de considérer la syntaxe et la sémantique comme deux choses complètement distinctes. Cela peut paraître choquant, mais il se peut que ce ne soit pas le cas. Je pense que ce que vous voulez dans votre langage peut être lié à la façon dont vous l'exprimez.
J'ai récemment discuté avec Robert Morris, et il a souligné que la surcharge d'opérateur est un avantage plus important dans les langages avec une syntaxe infixe. Dans un langage avec une syntaxe préfixe, toute fonction que vous définissez est en fait un opérateur. Si vous souhaitez définir un plus pour un nouveau type de nombre que vous avez créé, vous pouvez simplement définir une nouvelle fonction pour les ajouter. Si vous faites cela dans un langage avec une syntaxe infixe, il y a une grande différence d'apparence entre l'utilisation d'un opérateur surchargé et un appel de fonction.
1. Nouveaux langages de programmation.
Dans les années 1970, il était à la mode de concevoir de nouveaux langages de programmation. Récemment, ce n'est plus le cas. Mais je pense que les logiciels basés sur serveur vont remettre les nouveaux langages à la mode. Avec les logiciels basés sur serveur, vous pouvez utiliser n'importe quel langage que vous voulez, donc si quelqu'un conçoit un langage qui semble réellement meilleur que les autres disponibles, il y aura des gens qui prendront le risque de l'utiliser.
2. Partage du temps.
Richard Kelsey a avancé cette idée comme une idée qui a fait son retour dans le dernier panel, et je suis entièrement d'accord avec lui. Je pense (et c'est apparemment le cas de Microsoft) que la plupart des calculs vont se déplacer du bureau vers des serveurs distants. En d'autres termes, le partage du temps est de retour. Et je pense qu'il faudra le prendre en charge au niveau du langage. Par exemple, je sais que Richard et Jonathan Rees ont beaucoup travaillé à la mise en œuvre de la planification des processus dans le schéma 48.
3. Efficacité.
Récemment, il a commencé à sembler que les ordinateurs étaient enfin assez rapides. On a commencé à entendre parler de plus en plus de byte code, ce qui, à mon avis, laisse penser que nous avons le sentiment d'avoir des cycles à revendre. Mais je ne pense pas que ce soit le cas avec les logiciels basés sur des serveurs. Quelqu'un devra payer pour les serveurs sur lesquels les logiciels tournent, et le nombre d'utilisateurs qu'ils peuvent prendre en charge par machine sera le diviseur de leur coût d'investissement.
Je pense donc que l'efficacité sera importante, au moins en ce qui concerne les goulots d'étranglement informatiques. Il sera particulièrement important d'effectuer des E/S rapides, car les applications basées sur un serveur effectuent beaucoup d'E/S.
Il se peut que le byte code ne soit pas une victoire finale. Sun et Microsoft semblent se livrer une sorte de bataille du byte code en ce moment. Mais ils le font parce que le byte code est un endroit pratique pour s'insérer dans le processus, et non parce que le byte code est en soi une bonne idée. Il se peut que tout ce champ de bataille soit contourné. Ce serait plutôt amusant.
1. Clients.
Ce n’est qu’une supposition, mais je pense que le modèle gagnant pour la plupart des applications sera purement basé sur le serveur. Concevoir un logiciel qui fonctionne en partant du principe que tout le monde aura votre client, c’est comme concevoir une société en partant du principe que tout le monde sera honnête. Ce serait certainement pratique, mais il faut partir du principe que cela n’arrivera jamais.
Je pense qu'il y aura une prolifération d'appareils dotés d'un accès au Web, et tout ce que vous pourrez supposer à leur sujet est qu'ils peuvent prendre en charge du HTML et des formulaires simples. Aurez-vous un navigateur sur votre téléphone portable ? Y aura-t-il un téléphone dans votre Palm Pilot ? Votre Blackberry aura-t-il un écran plus grand ? Pourrez-vous naviguer sur le Web sur votre Gameboy ? Votre montre ? Je ne sais pas. Et je n'ai pas besoin de savoir si je parie que tout se trouvera sur le serveur. C'est tellement plus robuste d'avoir tous les cerveaux sur le serveur .
2. Programmation orientée objet.
Je sais que c'est un sujet controversé, mais je ne pense pas que la programmation orientée objet soit si importante. Je pense que c'est un bon modèle pour certains types d'applications qui nécessitent ce type spécifique de structure de données, comme les systèmes de fenêtres, les simulations et les programmes de CAO. Mais je ne vois pas pourquoi cela devrait être le modèle de toute la programmation.
Je pense que si les gens des grandes entreprises aiment la programmation orientée objet, c'est en partie parce qu'elle génère beaucoup de ce qui ressemble à du travail. Quelque chose qui pourrait naturellement être représenté comme une liste d'entiers, par exemple, peut maintenant être représenté comme une classe avec toutes sortes d'échafaudages et d'agitation.
Un autre attrait de la programmation orientée objet est que les méthodes vous donnent certains des effets des fonctions de première classe. Mais ce n'est pas nouveau pour les programmeurs Lisp. Lorsque vous avez de véritables fonctions de première classe, vous pouvez simplement les utiliser de la manière qui convient à la tâche à accomplir, au lieu de tout forcer dans un moule de classes et de méthodes.
Ce que cela signifie pour la conception du langage, je pense, c'est qu'il ne faut pas intégrer trop profondément la programmation orientée objet. La solution consiste peut-être à proposer des éléments sous-jacents plus généraux et à laisser les gens concevoir les systèmes d'objets qu'ils souhaitent sous forme de bibliothèques.
3. Conception par comité.
Confier la conception de son langage à un comité est un véritable piège, et pas seulement pour les raisons que tout le monde connaît. Tout le monde sait que les comités ont tendance à produire des conceptions inégales et incohérentes. Mais je pense que le plus grand danger est qu'ils ne prennent pas de risques. Lorsqu'une seule personne est aux commandes, elle peut prendre des risques sur lesquels un comité ne s'accorderait jamais.
Mais est-il nécessaire de prendre des risques pour concevoir un bon langage ? Beaucoup de gens pourraient penser que la conception d'un langage est un domaine dans lequel il faut s'en tenir à la sagesse conventionnelle. Je parie que ce n'est pas vrai. Dans tout ce que les gens font, la récompense est proportionnelle au risque. Pourquoi la conception d'un langage devrait-elle être différente ?