← Tous les articles

Philosophie de l'ingénierie : Roberto Ierusalimschy

Roberto Ierusalimschy, créateur de Lua

Points clés

  • Il a conçu le langage de script qui se cache dans une part énorme des logiciels que vous utilisez. Roberto Ierusalimschy a dirigé la conception de Lua, créé en 1993 au laboratoire Tecgraf de la PUC-Rio avec Luiz Henrique de Figueiredo et Waldemar Celes. Il fait tourner la logique de jeu de World of Warcraft, Roblox (via son dialecte Luau), Dota 2 et Garry’s Mod, sert à scripter Redis et nginx (à travers OpenResty), anime Adobe Lightroom et Wireshark, et s’embarque dans des appareils jusqu’à des robots dépourvus de système d’exploitation.127
  • Des mécanismes, pas des règles imposées. Le choix fondateur de Lua est un refus : il ne fournit ni système de classes, ni modèle objet, ni paradigme. Il vous offre quelques mécanismes puissants et généraux (tables, métatables, coroutines) et vous laisse bâtir vos propres abstractions par-dessus. « Lua n’impose aucun modèle d’objet ou de classe au programmeur », écrivaient ses concepteurs ; à la place, ils « fournissent des mécanismes flexibles » afin que vous puissiez construire le modèle qui convient à l’application.3
  • La petite taille est une qualité, pas une limite. L’implémentation de référence est minuscule et limpide : le code source de Lua 5.1 compte environ 17 000 lignes de C, la distribution complète tient sur une disquette, et l’interpréteur compilé pèse à peu près 143 Ko. La plupart des langages de script sont un ordre de grandeur plus volumineux ; Lua reste petit précisément parce qu’il est destiné à être embarqué, et c’est la simplicité qui rend possible une implémentation petite et rapide.3
  • La portabilité et l’embarquabilité étaient des objectifs de conception dès le premier jour. Lua est écrit en « C propre » — l’intersection du C et du C++ — et « se compile immédiatement sur la plupart des plateformes », de Linux et Windows aux appareils portables et aux microcontrôleurs. Une API C bien définie permet à un programme hôte de le contrôler et de l’étendre entièrement, ce qui explique précisément pourquoi l’industrie du jeu l’a adopté comme un quasi-standard.34

Le principe

« Nous ne voulions pas faire de Lua un langage orienté objet, parce que nous ne voulions pas figer un paradigme de programmation pour Lua… Lua n’impose aucun modèle d’objet ou de classe au programmeur. À la place… nous avons décidé de fournir des mécanismes flexibles qui permettraient au programmeur de construire le modèle convenant à l’application. » — Roberto Ierusalimschy, Luiz Henrique de Figueiredo et Waldemar Celes, The Evolution of Lua3

Concevoir un langage, c’est le plus souvent accumuler des décisions imposées. Une équipe décide que les objets doivent fonctionner de telle façon, que la gestion des erreurs doit ressembler à ceci, que la concurrence se traduit par des threads, de l’asynchrone ou des acteurs — et elle inscrit ces décisions dans le langage, si bien que chaque programme qui y est écrit hérite de ces choix. Ces décisions sont généralement raisonnables. Le problème, c’est que ce sont des décisions, prises une fois pour toutes, pour tout le monde, par des gens qui ne pouvaient pas connaître votre application. L’instinct de Ierusalimschy allait dans l’autre sens. Plutôt que de décider à votre place, Lua vous tend un petit ensemble de mécanismes généraux et s’efface, pour que vous puissiez construire les règles dont votre problème a réellement besoin.3

Le cas le plus clair est l’orientation objet. Au début des années 1990, alors que la programmation orientée objet était au sommet de sa mode, les utilisateurs pressaient l’équipe de Lua d’ajouter classes et héritage. Elle a refusé — non parce que l’OO était une erreur, mais parce que figer un seul modèle était une erreur pour un langage destiné à être embarqué dans des applications extrêmement diverses. Les objets et les classes « pouvaient être implémentés avec des tables si nécessaire », raisonnaient-ils, puisqu’une table peut contenir à la fois des données et des méthodes, et que les fonctions sont des valeurs de première classe.3 Aussi, au lieu d’un système d’objets, ils ont bâti une sémantique extensible — un mécanisme qui vous laisse intervenir sur le comportement des tables — et ont laissé les utilisateurs assembler eux-mêmes l’héritage, les valeurs par défaut, les vues en lecture seule et des hiérarchies de classes complètes. « La sémantique extensible est devenue une marque de fabrique de Lua », écrivaient-ils, et ils n’ont « pas changé d’avis à ce jour ».3

Ce refus n’est tenable que grâce à trois autres engagements qui l’accompagnent. La simplicité — le langage reste assez petit pour que les mécanismes soient compréhensibles et l’implémentation correcte. La petite taille érigée en qualité — toute l’implémentation de référence représente environ 17 000 lignes de C propre, assez peu pour qu’ajouter Lua à une application « ne l’alourdisse pas ».3 Et la portabilité — écrire dans l’intersection du C et du C++ signifie que le même code source se compile partout, d’un superordinateur à un capteur.3 Donnez aux gens quelques leviers affûtés et généraux plutôt qu’une armoire pleine de boutons décidés d’avance, et gardez l’ensemble assez petit pour l’emporter n’importe où. Voilà le principe, et tout le reste de Lua en découle.

Contexte

Roberto Ierusalimschy est né le 21 mai 1960 à Rio de Janeiro, et toute sa carrière est restée proche d’une seule institution — l’Université pontificale catholique de Rio de Janeiro (PUC-Rio), où il a obtenu son doctorat en informatique en 1990 et où il est professeur titulaire d’informatique. Il a effectué un post-doctorat à l’Université de Waterloo et un passage comme professeur invité à Stanford, mais la PUC-Rio est son port d’attache, et l’histoire de Lua est indissociable d’un laboratoire bien précis qui s’y trouve.5

Ce laboratoire, c’est Tecgraf, le Computer Graphics Technology Group, fondé en 1987 pour construire des outils logiciels destinés à des clients industriels — l’un des plus importants étant, hier comme aujourd’hui, la compagnie pétrolière brésilienne Petrobras.3 L’origine de Lua tient en partie à la politique commerciale brésilienne. De 1977 à 1992, le Brésil a maintenu une politique de fortes barrières commerciales — une « réserve de marché » — sur le matériel et les logiciels informatiques, animée par la conviction nationaliste que le pays pouvait et devait fabriquer les siens. Dans ce contexte, les clients de Tecgraf « ne pouvaient se permettre, ni politiquement ni financièrement, d’acheter des logiciels sur mesure à l’étranger ». Acheter des outils étrangers impliquait un « processus bureaucratique compliqué pour prouver que leurs besoins ne pouvaient pas être satisfaits par des entreprises brésiliennes ». Ces restrictions, conjuguées à l’isolement géographique du Brésil par rapport aux autres centres de recherche, « ont conduit Tecgraf à implémenter de zéro les outils de base dont il avait besoin ».3 Lua est, de l’aveu même de ses concepteurs, « le seul langage créé dans un pays en développement à avoir atteint une portée mondiale ».3

Avant Lua, il y avait deux petits langages, tous deux conçus pour Petrobras. DEL — « data-entry language » — générait des interfaces graphiques pour que les ingénieurs puissent saisir les entrées de simulateurs en cliquant sur un diagramme plutôt qu’en éditant des colonnes de chiffres.3 SOL — « Simple Object Language » — était un langage de configuration pour un générateur de rapports, doté d’une syntaxe de déclaration de types inspirée de BibTeX.3 Au début de 1993, tous deux avaient débordé de leur cadre initial : les utilisateurs de DEL voulaient un vrai contrôle de flux, et SOL avait besoin de puissance procédurale. Au milieu de 1993, Ierusalimschy, de Figueiredo et Celes conclurent que les deux pouvaient être remplacés par un langage unique, plus puissant — et l’équipe Lua était née.3 Le nom est une petite plaisanterie qui est restée. SOL signifie « soleil » en portugais ; un ami de Tecgraf, Carlos Henrique Levy, suggéra d’appeler le successeur « Lua » — « lune » en portugais.3 En juillet 1993, Waldemar Celes avait achevé la première implémentation, réalisée comme projet de cours encadré par Ierusalimschy et suivant le précepte de l’Extreme Programming : « la chose la plus simple qui puisse fonctionner ».3

Le travail

Tables et métatables : une seule structure de données, un seul mécanisme

Commençons par la table, car elle est le langage tout entier en miniature. Lua n’offre qu’un seul mécanisme de structuration des données — la table, son terme pour un tableau associatif — et cette unique structure remplit le rôle des enregistrements, des tableaux, des ensembles, des listes, des modules et des objets.3 « Bien que la plupart des langages de script proposent des tableaux associatifs », notent les concepteurs, « dans aucun autre langage les tableaux associatifs ne jouent un rôle aussi central ».3 Un enregistrement est une table indexée par des noms de champs ; un tableau est une table indexée par des entiers ; un objet est une table qui se trouve contenir à la fois des données et des méthodes. Un seul mécanisme, de multiples usages — c’est exactement le pari « des mécanismes, pas des règles imposées » appliqué aux données.

Le levier qui rend les tables programmables, c’est la métatable. Normalement, rechercher une clé que la table ne possède pas renvoie nil. Mais vous pouvez doter une table d’une métatable — une seconde table qui décrit comment la première doit se comporter dans des situations inhabituelles. L’entrée la plus importante est __index : lorsqu’une recherche échoue, Lua consulte le __index de la métatable, qui peut pointer vers une autre table à explorer ensuite. Enchaînez-les, et vous obtenez un héritage bâti uniquement à partir de tables et d’une simple redirection. Le même mécanisme, sous différentes métaméthodes, vous donne la surcharge d’opérateurs, les valeurs par défaut, les proxys en lecture seule et les champs paresseux. Rien de tout cela n’est une fonctionnalité du langage au sens habituel — c’est un seul et même mécanisme, employé sous différentes formes.3

Ce mécanisme n’est pas arrivé d’un seul tenant — son évolution est elle-même une leçon de retenue. Il a débuté dans Lua 2.1 (1995) sous la forme de « fallbacks » : des points d’accroche que Lua appelait lorsqu’une opération était appliquée au « mauvais » type de valeur, afin que le programmeur puisse décider de la suite.3 Le fallback d’indexation de table permettait aux userdata et à d’autres valeurs de « se comporter comme des tables », prenant en charge « de nombreuses formes d’héritage (par délégation) ».3 Les fallbacks étaient globaux — un seul point d’accroche par événement —, ce qui les rendait malcommodes à partager entre bibliothèques ; aussi Lua 3.0 (1997) les a-t-il remplacés par des « tag methods » propres à chaque type, et Lua 5.0 (2003) a tout unifié en métatables et métaméthodes, la forme que Lua utilise aujourd’hui. (Le terme « métatable » a été suggéré par Rici Lake en 2001.)3 Chaque étape généralisait le mécanisme au lieu d’empiler de nouvelles fonctionnalités — le même instinct qui faisait que le langage continuait de refuser de fournir un système de classes.

L’embarquabilité, l’API C, et pourquoi les jeux ont adopté Lua

Lua n’est pas vraiment censé être un langage autonome. Ses concepteurs le qualifient de « langage d’extension extensible » — un langage d’extension parce qu’il étend une application hôte par la configuration et le script, et extensible parce qu’il peut à son tour être étendu par des fonctions C.3 La charnière est une API C bien définie qui « permet une communication complète entre le code Lua et le code externe », bâtie autour d’une métaphore de pile limpide pour faire transiter les valeurs entre Lua et l’hôte. L’API permet à Lua de s’interfacer non seulement avec le C et le C++, mais aussi, à travers eux, avec Fortran, Java, C# et d’autres langages encore.3

La récompense est venue des jeux, et l’histoire est précise. En janvier 1997, Bret Mogilefsky — programmeur principal du jeu d’aventure Grim Fandango de LucasArts — annonça à l’équipe de Lua qu’il avait remplacé le langage de script maison du jeu par Lua, et qu’« une énorme partie du jeu avait été écrite en Lua ».3 Mogilefsky en parla lors d’une table ronde de la Game Developers’ Conference, et de là « Lua se répandit de bouche à oreille parmi les développeurs de jeux pour devenir une compétence assurément monnayable dans l’industrie du jeu ».3 L’adéquation est structurelle. Un moteur de jeu est exactement le genre d’hôte qui tire parti d’une couche de script embarquée — le gros du travail (rendu, physique) reste en C++ rapide, tandis que la logique de jeu, les quêtes et les comportements vivent dans de petits scripts Lua que les concepteurs peuvent éditer et recharger sans recompiler le moteur. Petit, rapide, portable et embarquable : c’était précisément le profil dont un jeu avait besoin, et Lua avait été conçu pour cela dès sa première version.34

Les coroutines, et une implémentation petite et rapide

Le troisième grand mécanisme est la coroutine — et, comme l’OO, il relève d’un refus délibéré d’une règle imposée par l’équipe. Tout au long de la fin des années 1990, les utilisateurs réclamèrent le multithreading, et le geste évident aurait été d’adopter le modèle standard de threads préemptifs à mémoire partagée. L’équipe de Lua s’y refusa, pour deux raisons : implémenter des threads préemptifs en C exige des primitives « qui ne font pas partie de l’ANSI C », ce qui aurait brisé la portabilité de Lua, et — plus fondamentalement — « nous ne croyions pas (et ne croyons toujours pas) au modèle de multithreading standard », où « personne ne peut écrire des programmes corrects dans un langage où “a=a+1” n’est pas déterministe ».3 Aussi, au lieu de threads, ils livrèrent des coroutines dans Lua 5.0 (2003) : un mécanisme de multitâche coopératif et non préemptif où une fonction peut se suspendre elle-même puis reprendre plus tard exactement là où elle s’était arrêtée.3 Les coroutines vous donnent l’expressivité de la concurrence — générateurs, ordonnanceurs coopératifs, machines à états — sans le non-déterminisme qui rend les threads à mémoire partagée si difficiles à maîtriser. Un mécanisme, pas une règle imposée, une fois de plus.

Sous tout cela repose une implémentation rapide précisément parce qu’elle est petite. La machine virtuelle de Lua reposait sur une pile jusqu’à Lua 4.0 ; avec Lua 5.0, elle est devenue fondée sur des registres, ce qui a donné au générateur de code davantage de marge pour optimiser et a réduit le nombre d’instructions de la machine virtuelle qu’un programme classique exécute. Les concepteurs notent que « la machine virtuelle de Lua 5.0 fut la première machine virtuelle fondée sur des registres à connaître un large usage ».3 La mémoire est gérée par un ramasse-miettes incrémental (introduit dans Lua 5.1) qui accomplit son travail par petites étapes plutôt que par de longues pauses bloquant tout le programme — un point important pour les boucles temps réel d’un jeu.3 Des bancs d’essai indépendants placent Lua parmi les plus rapides des langages de script interprétés, assez rapide pour que, de l’aveu des concepteurs, « plus de 40 % d’Adobe Lightroom soit écrit en Lua », soit environ 100 000 lignes.3

Le langage de programmation Lua

La portée de Lua : de World of Warcraft à un robot sans système d’exploitation

Mettez tout bout à bout et Lua est devenu la couche de script invisible d’une part énorme du logiciel. Dans les jeux, World of Warcraft expose la totalité de son interface à Lua pour que les joueurs puissent écrire des add-ons ; Roblox a bâti Luau, un dialecte de Lua, comme le langage avec lequel des millions de jeunes créateurs apprennent à programmer ; Dota 2, Crysis et Garry’s Mod l’embarquent aussi.1 Hors des jeux, Redis exécute des scripts Lua de façon atomique au sein de la base de données ; nginx, à travers la distribution OpenResty, utilise Lua pour programmer le serveur web lui-même ; Adobe Lightroom et Wireshark reposent largement sur lui ; Neovim a adopté Lua comme langage de configuration et d’extension de première classe.1 Et parce que l’interpréteur est petit et portable, Lua atteint du matériel qui ne possède presque rien d’autre — les concepteurs racontent l’histoire de Crazy Ivan, un robot vainqueur de la RoboCup dont le « cerveau » faisait tourner Lua « directement sur un processeur Motorola Coldfire 5206e sans aucun système d’exploitation ; en d’autres termes, Lua était le système d’exploitation ».7 Un petit langage, conçu dans un laboratoire de Rio sous le régime de restrictions commerciales, s’est retrouvé partout — parce qu’il n’exigeait presque rien et vous tendait les leviers pour construire le reste.

La méthode

Parcourez DEL, SOL, la métatable, les coroutines et trente ans de refus d’alourdir le langage, et les mêmes gestes reviennent. La méthode de Ierusalimschy tient moins d’un slogan que d’un ensemble d’engagements permanents.

Livrez des mécanismes, pas des règles imposées. L’habitude fondatrice consiste à fournir un levier général et à refuser de décider de la manière dont il doit être utilisé. Pas de système de classes intégré, pas de modèle de concurrence figé — juste des tables, des métatables et des coroutines, à partir desquels vous bâtissez ce dont votre application a besoin. La leçon générale dépasse de loin la conception de langages : les outils les plus durables sont ceux qui confèrent une capacité sans dicter la forme de la solution. C’est l’inverse de « l’unique façon évidente de faire » de Guido van Rossum, et le contraste est précisément le propos : les deux sont cohérents, et savoir quelle philosophie votre outil doit incarner est la véritable décision.3

Gardez-le assez petit pour être correct et pour l’emporter n’importe où. L’implémentation de référence de Lua compte environ 17 000 lignes de C propre, un ordre de grandeur de moins que les autres langages de script, et cette petitesse est une qualité délibérée — c’est elle qui rend le langage embarquable, portable et digne de confiance. La discipline consiste à continuer de retrancher jusqu’à ce qu’enlever une chose de plus le casse, ce qui fait de Lua le miroir logiciel du minimalisme impitoyable de Sophie Wilson dans ARM — dépouiller jusqu’à l’essence porteuse et laisser l’efficacité en découler gratuitement. C’est le produit minimum digne d’être livré à l’échelle d’un environnement d’exécution de langage.3

Résistez à la fonctionnalité qu’on vous réclame jusqu’à ce que vous trouviez le mécanisme qui la sous-tend. Quand les utilisateurs ont exigé des objets, Lua leur a donné une sémantique extensible ; quand ils ont exigé des threads, il leur a donné des coroutines. Chaque fois, l’équipe a décliné la règle particulière et livré le mécanisme plus général qui laissait les utilisateurs construire eux-mêmes cette règle — et, fait crucial, n’a pas changé d’avis des années plus tard.3 C’est la barrière des preuves appliquée aux demandes de fonctionnalités : n’ajoutez pas la chose parce qu’on la demande ; découvrez quel problème elle résout et si un mécanisme que vous possédez déjà peut le résoudre.

Généralisez, n’accumulez pas. La métatable n’est pas arrivée d’un seul tenant — elle est passée des fallbacks aux tag methods puis aux métaméthodes, et chaque étape remplaçait le mécanisme précédent par un plus général au lieu de visser une nouvelle fonctionnalité à côté.3 La leçon est d’évoluer par unification, non par addition, pour que le langage gagne en capacité tout en gardant la même taille — la même économie de moyens que Thompson et Ritchie employèrent pour bâtir Unix à partir de petites pièces composables.

Laissez la contrainte concevoir l’outil. Lua existe parce que les barrières commerciales du Brésil ont forcé Tecgraf à fabriquer ses propres logiciels, et sa portabilité existe parce que les clients du laboratoire faisaient tourner « une collection très diverse de plateformes informatiques ».3 Plutôt que de traiter ces contraintes comme des handicaps, Ierusalimschy les a laissées orienter la conception vers quelque chose de plus petit, plus net et plus portable qu’une équipe richement dotée aurait vraisemblablement produit — la leçon que la rareté, prise au sérieux, est un outil de conception et non une excuse.3

Chaîne d’influence

Qui l’a façonné

Scheme et la tradition Lisp. Les concepteurs disent explicitement que « l’influence de Scheme sur Lua s’est progressivement accrue », devenant « une source d’inspiration, en particulier avec l’introduction des fonctions anonymes et de la portée lexicale complète ».3 Comme Scheme, Lua est à typage dynamique, traite les fonctions comme des valeurs de première classe ordinaires et garde un noyau réduit — la conviction qu’un langage peut être puissant en étant minimal plutôt que vaste. (Influence formatrice)

DEL et SOL, les deux petits langages. Lua n’a pas jailli de la théorie ; il est né de deux langages dédiés conçus pour Petrobras. SOL a apporté la syntaxe de constructeur de table pour décrire les données, et l’expérience des deux a appris à l’équipe que « de larges parties d’applications complexes pouvaient être écrites à l’aide de langages de script embarquables » — la prise de conscience sur laquelle, selon leurs propres mots, la naissance de Lua reposait.3 (Influence directe)

La réserve de marché brésilienne. Les barrières commerciales en vigueur de 1977 à 1992 constituent une influence improbable mais bien réelle : c’est à cause d’elles que Tecgraf a construit ses propres outils, et la diversité des plateformes de ses clients explique pourquoi la portabilité est devenue un objectif de conception de premier ordre. C’est la politique publique qui a fait le langage. (Influence formatrice)

Qui il a façonné

La couche de script de l’industrie du jeu. À partir de Grim Fandango, Lua est devenu un quasi-choix par défaut pour embarquer la logique de jeu, et le schéma qu’il a popularisé — moteur rapide en C++, comportement éditable dans un script embarqué — est aujourd’hui une pratique courante. Le Luau de Roblox a appris à toute une génération d’enfants à programmer dans un dialecte de Lua. (Influence structurante pour le domaine)

Les logiciels embarqués et systèmes. Redis, nginx/OpenResty, Wireshark, Neovim et d’innombrables appareils ont adopté Lua comme couche de script précisément parce qu’il exige si peu. Peu de langages s’étendent d’une base de données à un analyseur réseau jusqu’à un robot fonctionnant à même le métal.

Les concepteurs de langages qui chérissent la petite taille. Lua se dresse comme la preuve concrète qu’un noyau minuscule et agnostique vis-à-vis des paradigmes peut surclasser de grands langages dotés d’opinions dans la niche de l’embarqué — un argument qui résonne dans toute conception à environnement d’exécution minimal et « mécanisme plutôt que cadre » depuis lors.

Le fil conducteur

Ierusalimschy se tient à l’un des pôles du long débat de cette série sur la quantité de décisions qu’un outil doit prendre à votre place. Guido van Rossum a bâti Python sur « il devrait y avoir une seule façon évidente de faire » et l’a livré piles incluses — le langage a des opinions, et les suivre est le chemin de moindre résistance. Bjarne Stroustrup a conçu un C++ assez riche pour exprimer presque n’importe quel paradigme, payant cette richesse en taille et en complexité. Ierusalimschy a pris le chemin inverse des deux : ne livrer presque aucune règle imposée, presque aucune fonctionnalité, juste quelques mécanismes généraux et un environnement d’exécution de 17 000 lignes, et laisser l’utilisateur construire le reste. Il est le miroir logiciel de Sophie Wilson, dont l’ARM l’a emporté en étant réduit à moins de 25 000 transistors — Lua est cette même petitesse impitoyable en C, et comme la faible consommation accidentelle de l’ARM, sa petite taille s’est révélée être précisément ce qui lui a permis de conquérir un domaine (l’embarqué) pour lequel personne ne l’avait conçu. Là où van Rossum dit voici la façon évidente et Stroustrup voici toutes les façons, Ierusalimschy dit : voici les leviers — vous décidez de ce que vous construisez, et je garderai l’ensemble assez petit pour l’emporter n’importe où. (Passerelle de la série)

Ce que j’en retiens

La leçon que je retiens de Ierusalimschy, c’est que la chose la plus puissante que vous puissiez tendre à quelqu’un est un mécanisme, pas une règle imposée. Il est tentant, quand on construit un outil, d’y inscrire son opinion sur la façon dont il doit être utilisé — de livrer le système de classes, le cadre, l’unique flux de travail béni. Toute la carrière de Lua est un argument selon lequel l’inverse vieillit mieux. En refusant de figer un modèle objet et en livrant la métatable à la place, le langage a permis aux utilisateurs de bâtir des schémas d’héritage que ses concepteurs n’avaient jamais imaginés, dans des jeux, des bases de données et des éditeurs qu’ils n’avaient jamais anticipés. Quand je construis quelque chose aujourd’hui, la question que j’emprunte à Lua est de savoir si je livre une décision ou une capacité — car la décision sert les cas que je peux voir aujourd’hui, et la capacité sert ceux que je ne peux pas voir.

La seconde leçon, c’est que la petite taille n’est pas une contrainte que l’on tolère — c’est une qualité que l’on protège. Il aurait été facile, au fil de trente ans de pression des utilisateurs, de laisser Lua devenir un grand langage doté d’un mot-clé de classe, d’une bibliothèque de threads et d’un cadre standard pour tout. L’équipe a refusé, et c’est ce refus qui fait que Lua tient sur une disquette, se compile partout et s’embarque dans le cerveau à nu d’un robot. La discipline de rester petit — généraliser plutôt qu’accumuler, décliner la fonctionnalité jusqu’à trouver le mécanisme qui la sous-tend — est plus difficile que la discipline d’ajouter, et bien plus précieuse. C’est la qualité est la seule variable lue comme une forme de retenue : la bonne petite chose, défendue pendant des décennies, devient l’infrastructure sur laquelle tout le reste peut s’appuyer.

FAQ

Qui est Roberto Ierusalimschy et qu’a-t-il créé ?

Roberto Ierusalimschy est un informaticien brésilien, né en 1960 à Rio de Janeiro et professeur titulaire d’informatique à la PUC-Rio. Il est le concepteur principal de Lua, le langage de script petit, rapide et embarquable qu’il a créé en 1993 au laboratoire Tecgraf de la PUC-Rio avec Luiz Henrique de Figueiredo et Waldemar Celes. Il est aussi l’auteur du livre Programming in Lua et le créateur de LPeg, une bibliothèque de filtrage par motifs, et a coécrit l’histoire de référence du langage, « The Evolution of Lua ».356

Que signifie « des mécanismes, pas des règles imposées » dans Lua ?

Cela signifie que Lua vous donne quelques mécanismes puissants et généraux plutôt que d’imposer des décisions figées. L’exemple le plus clair est l’orientation objet : Lua ne possède aucun système de classes intégré. À la place, il offre des tables (qui peuvent contenir à la fois des données et des méthodes) et des métatables (qui vous laissent personnaliser le comportement d’une table), et vous construisez vous-même l’héritage, les classes ou tout autre modèle objet. Les concepteurs ont écrit que « Lua n’impose aucun modèle d’objet ou de classe au programmeur » et ont choisi de « fournir des mécanismes flexibles » à la place — une position qu’ils tiennent depuis 1993.3

Pourquoi Lua est-il si largement utilisé dans les jeux et les systèmes embarqués ?

Parce qu’il a été conçu dès le départ pour être petit, rapide, portable et facile à embarquer. L’implémentation de référence représente environ 17 000 lignes de C ANSI propre qui se compile presque partout, l’interpréteur compilé pèse à peu près 143 Ko, et une API C bien définie permet à un programme hôte de le contrôler entièrement. Ce profil est exactement ce dont un moteur de jeu ou un appareil embarqué a besoin — le gros du travail en C/C++, la logique éditable dans de petits scripts — c’est pourquoi il sert à scripter World of Warcraft, Roblox (via Luau), Redis, nginx/OpenResty, Adobe Lightroom et des appareils jusqu’à des robots à même le métal.137

D’où vient le nom « Lua » ?

Lua signifie « lune » en portugais. Il a été nommé comme successeur d’un langage Tecgraf antérieur appelé SOL — « Simple Object Language », et aussi « soleil » en portugais. Un collègue de Tecgraf, Carlos Henrique Levy, suggéra le nom « Lua » pour le nouveau langage, complétant la progression du soleil à la lune. Tout le projet est né de deux petits langages, DEL et SOL, conçus pour la compagnie pétrolière brésilienne Petrobras.3


Sources


  1. « Lua (programming language) », Wikipédia. Lua a été créé en 1993 par Roberto Ierusalimschy, Luiz Henrique de Figueiredo et Waldemar Celes au Computer Graphics Technology Group (Tecgraf) de l’Université pontificale catholique de Rio de Janeiro (PUC-Rio), au Brésil ; implémenté en C ANSI, sous licence MIT, doté d’une machine virtuelle fondée sur des registres depuis Lua 5.0, d’un ramasse-miettes, de coroutines et de fonctions de première classe. Les implémentations de référence récentes restent petites (l’article note que Lua 5.5.0 comprend environ 32 000 lignes de C). Parmi les utilisateurs documentés figurent les jeux World of Warcraft, Roblox (qui a développé Luau, un dérivé de Lua), Dota 2, Crysis et Garry’s Mod, ainsi que des logiciels hors jeu dont Redis, nginx (via OpenResty), Adobe Lightroom, Wireshark et Neovim. 

  2. « Roberto Ierusalimschy: Known for Lua Programming Language », machaddr (profil biographique). Résume le rôle de Ierusalimschy comme créateur et architecte principal de Lua, développé avec Luiz Henrique de Figueiredo et Waldemar Celes à la PUC-Rio, publié pour la première fois en 1993 ; relève l’usage mondial de Lua dans des logiciels dont World of Warcraft et Adobe Lightroom, sa qualité d’auteur de Programming in Lua et sa création de la bibliothèque LPeg. 

  3. Roberto Ierusalimschy, Luiz Henrique de Figueiredo et Waldemar Celes, « The Evolution of Lua », Proceedings of the Third ACM SIGPLAN Conference on the History of Programming Languages (HOPL III), 2007. Source primaire. « Lua est un langage de script né en 1993 à la PUC-Rio. » « Dès le départ, Lua a été conçu pour être simple, petit, portable, rapide et facilement embarqué dans des applications. » L’unique structure de données : « il offre une seule sorte de structure de données, la table ». Implémenté en « C propre », « l’intersection du C et du C++ », et « se compile immédiatement sur la plupart des plateformes ». Petite taille : le code source de Lua 5.1 compte « environ 17 000 lignes de C », l’archive « tient confortablement sur une disquette », et « l’interpréteur Lua construit avec toutes les bibliothèques Lua standard occupe 143 Ko ». « plus de 40 % d’Adobe Lightroom est écrit en Lua (ce qui représente environ 100 000 lignes de code Lua) ». Sur la politique commerciale du Brésil : « De 1977 à 1992, le Brésil avait une politique de fortes barrières commerciales (appelée “réserve de marché”) pour le matériel et les logiciels informatiques », et « ces raisons ont conduit Tecgraf à implémenter de zéro les outils de base dont il avait besoin » ; Lua est « le seul langage créé dans un pays en développement à avoir atteint une portée mondiale ». Les prédécesseurs DEL (« data-entry language ») et SOL (« Simple Object Language »). Nom : SOL signifie soleil en portugais, et « un ami de Tecgraf (Carlos Henrique Levy) suggéra le nom “Lua” (lune en portugais), et Lua naquit ». Première implémentation achevée en juillet 1993 suivant « la chose la plus simple qui puisse fonctionner ». Sur « des mécanismes, pas des règles imposées » : « nous ne voulions pas faire de Lua un langage orienté objet, parce que nous ne voulions pas figer un paradigme de programmation pour Lua » ; « Lua n’impose aucun modèle d’objet ou de classe au programmeur » ; « nous avons décidé de fournir des mécanismes flexibles qui permettraient au programmeur de construire le modèle convenant à l’application » ; « la sémantique extensible est devenue une marque de fabrique de Lua ». Évolution du mécanisme : fallbacks (Lua 2.1, 1995) → tag methods (Lua 3.0, 1997) → métatables et métaméthodes (Lua 5.0, 2003) ; les fallbacks d’indexation de table prenaient en charge « de nombreuses formes d’héritage (par délégation) » ; le terme « métatable » a été suggéré par Rici Lake en 2001. Lua comme « langage d’extension extensible » doté d’une API C permettant « une communication complète entre le code Lua et le code externe ». Jeux : en janvier 1997, Bret Mogilefsky, programmeur principal de Grim Fandango de LucasArts, rapporta qu’« une énorme partie du jeu avait été écrite en Lua », après quoi « Lua se répandit de bouche à oreille parmi les développeurs de jeux pour devenir une compétence assurément monnayable dans l’industrie du jeu ». Concurrence : implémenter des threads préemptifs exige des primitives « ne faisant pas partie de l’ANSI C », et « nous ne croyions pas (et ne croyons toujours pas) au modèle de multithreading standard… personne ne peut écrire des programmes corrects dans un langage où “a=a+1” n’est pas déterministe » ; le multitâche coopératif via coroutines a été fourni dans Lua 5.0 (2003). VM : « Depuis Lua 5.0, la machine virtuelle est fondée sur des registres », et « la machine virtuelle de Lua 5.0 fut la première machine virtuelle fondée sur des registres à connaître un large usage » ; le ramasse-miettes incrémental apparaît dans Lua 5.1. 

  4. « Lua: about », Lua.org (site officiel). « Lua est un langage de script puissant, efficace, léger et embarquable. » Il « est implémenté sous la forme d’une petite bibliothèque de fonctions C, écrite en C propre, le sous-ensemble commun du C standard et du C++ », et « fonctionne sur toutes sortes de systèmes Unix et Windows, ainsi que sur des appareils mobiles… des microprocesseurs embarqués… et des mainframes IBM ». Décrit Lua comme combinant « une syntaxe procédurale simple avec de puissantes constructions de description de données fondées sur des tableaux associatifs et une sémantique extensible », avec un typage dynamique, une gestion automatique de la mémoire par ramasse-miettes incrémental, et comme étant « rapide » et « portable ». 

  5. « Roberto Ierusalimschy », Wikipédia, corroboré par sa « fiche d’enseignant », Département d’informatique, PUC-Rio. Né le 21 mai 1960 à Rio de Janeiro, au Brésil ; doctorat en informatique de la PUC-Rio (1990) ; professeur titulaire d’informatique à la PUC-Rio ; travaux post-doctoraux à l’Université de Waterloo et professeur invité à Stanford (2012). Créateur et architecte principal du langage de programmation Lua, auteur de Programming in Lua (quatre éditions) et développeur de LPeg, une bibliothèque Lua pour implémenter des grammaires d’expressions d’analyse (parsing expression grammars). 

  6. « Programming in Lua », par Roberto Ierusalimschy, Lua.org. Le livre officiel sur Lua, écrit par son concepteur principal, décrivant la conception et l’usage du langage ; la première édition est disponible gratuitement en ligne. Renforce la conception de Lua autour des tables comme unique mécanisme de structuration des données, des métatables pour le comportement extensible, des fonctions de première classe et des coroutines pour le multitâche coopératif. 

  7. Roberto Ierusalimschy, Luiz Henrique de Figueiredo et Waldemar Celes, « The Evolution of Lua », HOPL III, 2007, note de bas de page sur l’usage embarqué. « Crazy Ivan, un robot qui a remporté la RoboCup en 2000 et 2001 au Danemark, avait un “cerveau” implémenté en Lua. Lua fonctionnait directement sur un processeur Motorola Coldfire 5206e sans aucun système d’exploitation (en d’autres termes, Lua était le système d’exploitation). Lua était stocké sur une ROM système et chargeait les programmes au démarrage depuis le port série. » Illustre la portée de Lua jusque dans les appareils embarqués à même le métal, conséquence de son implémentation petite et portable. 

Articles connexes

Philosophie de l'ingénierie : Guido van Rossum, la lisibilité compte

Guido van Rossum a bâti Python sur un seul pari : le code est lu bien plus souvent qu'il n'est écrit, si bien que le lan…

17 min de lecture

Philosophie de l'ingénierie : Grace Hopper, faire parler la machine en langage humain

Grace Hopper a construit le premier compilateur pour que les programmes s'écrivent en langage humain, a rendu la latence…

19 min de lecture

The Shader Gallery That Lied: Debugging 216 WebGL Presets

A user said the shader playground looked broken. Pixel-readback testing found 30 dead presets, 11 that never compiled, a…

11 min de lecture