
Il y a quelque temps, le créateur du langage de programmation Lua, Roberto Ierusalimschy, a visité notre bureau de Moscou. Nous lui avons également posé quelques questions que nous avons préparées avec la participation des utilisateurs de Habr.com. Et enfin, nous aimerions partager la version intégrale de cette interview.
- Commençons par quelques questions philosophiques. Imaginez, si vous recréiez Lua à partir de zéro, quelles trois choses changeriez-vous dans Lua?- Ouah! C'est une question difficile. Il y a tellement d'histoire intégrée dans la création et le développement de la langue. Ce n'était pas comme une grosse décision à la fois. Il y a des regrets, dont plusieurs que j'ai eu l'occasion de corriger au fil des ans. Les gens s'en plaignent tout le temps à cause de la compatibilité. Nous l'avons fait plusieurs fois. Je ne pense qu'à de petites choses.
- Global par défaut? Pensez-vous que c'est la voie?- Peut-ętre. Mais c'est très difficile pour les langages dynamiques. Peut-être que la solution sera de n'avoir aucun défaut par défaut, mais il serait alors difficile d'utiliser des variables.
Par exemple, vous devrez déclarer en quelque sorte toutes les bibliothèques standard. Vous voulez une ligne unique,
print(sin(x))
, puis vous devrez déclarer 'print' et aussi déclarer 'sin'. Il est donc assez étrange d'avoir des déclarations pour ce genre de scripts très courts.
Tout ce qui est plus grand ne devrait avoir aucun défaut, je pense. Local-by-default n'est pas la solution, il n'existe pas. C'est seulement pour les affectations, pas pour l'usage. Quelque chose que nous attribuons, puis nous utilisons et ensuite assignons, et il y a une erreur - complètement mystifiante.
Peut-être que global-by-default n'est pas parfait, mais pour sûr local-by-default n'est pas une solution. Je pense qu'une sorte de déclaration, peut-être une déclaration facultative ... Nous avons souvent eu cette proposition - une sorte de déclaration globale. Mais au final, je pense que le problème est que les gens demandent de plus en plus et nous abandonnons.
(sarcastique) Oui, nous allons faire une déclaration globale - ajouter ceci et cela et cela, éteindre cela, et à la fin nous comprenons que la conclusion finale ne satisfera pas la plupart des gens et nous ne mettrons pas toutes les options que tout le monde veut, donc on ne met rien. Au final, le mode strict est un compromis raisonnable.
Il y a ce problème: le plus souvent, nous utilisons des champs à l'intérieur des modules par exemple, alors vous avez à nouveau les mêmes problèmes. Ce n'est qu'un cas très spécifique d'erreurs que la solution générale devrait probablement inclure. Je pense donc que si vous le voulez vraiment, vous devez utiliser un langage typé statiquement.
- Global-by-default est également pratique pour les petits fichiers de configuration.- Oui, exactement, pour les petits scripts et ainsi de suite.
- Pas de compromis ici?- Non, il y a toujours des compromis. Il y a un compromis entre les petits scripts et les vrais programmes ou quelque chose comme ça.
- Donc, nous revenons à la première grande question: trois choses que vous changeriez si vous en aviez l'occasion. À mon avis, vous êtes très satisfait de ce que nous avons actuellement, n'est-ce pas?- Eh bien, ce n'est pas un grand changement, mais quand même ... Notre mauvaise dette qui est devenue un grand changement est nulle dans les tableaux. C'est quelque chose que je regrette vraiment. J'ai fait ce genre d'implémentation, une sorte de hack ... Avez-vous vu ce que j'ai fait? J'ai envoyé une version de Lua il y a environ six mois ou un an qui avait zéro dans les tableaux.
- Des valeurs nulles?- Exactement. Je pense que cela s'appelait nils dans les tableaux - ce qu'on appelle null. Nous avons piraté la grammaire pour la rendre quelque peu compatible.
- Pourquoi est-il nécessaire?- Je suis vraiment convaincu que c'est tout un problème de trous ... Je pense que la plupart des problèmes de nils dans les tableaux disparaîtraient, si nous pouvions avoir [nils dans les tableaux] ... Parce que le problème exact n'est pas nils dans les tableaux. Les gens disent que nous ne pouvons pas avoir de nils dans les tableaux, donc nous devrions avoir des tableaux séparés des tables. Mais le vrai problème est que nous ne pouvons pas avoir de nils dans les tableaux! Le problème vient donc des tables, pas de la façon dont nous représentons les tableaux. Si nous pouvions avoir nils dans les tableaux, alors nous aurions nils dans les tableaux sans rien d'autre. C'est donc quelque chose que je regrette vraiment, et beaucoup de gens ne comprennent pas comment les choses changeraient si Lua autorisait des nils dans les tableaux.
- Puis-je vous raconter une histoire sur Tarantool? Nous avons en fait notre propre implémentation de null, qui est un CDATA vers un pointeur nul. Nous l'utilisons lorsque des lacunes dans la mémoire sont nécessaires. Pour remplir des arguments de position lorsque nous faisons des appels à distance, etc. Mais nous en souffrons généralement car CDATA est toujours converti en «vrai». Donc, les nils dans les tableaux résoudraient beaucoup de nos problèmes.- Ouais, je sais. C'est exactement mon point - cela résoudrait beaucoup de problèmes pour beaucoup de gens, mais il y a un gros problème de compatibilité. Nous n'avons pas l'énergie de publier une version si incompatible, puis de briser la communauté et d'avoir une documentation différente pour Lua 5 et Lua 6, etc. Mais peut-être qu'un jour nous le publierons. Mais c'est vraiment un grand changement. Je pense que cela aurait dû être comme ça depuis le début - si c'était le cas, ce serait un changement trivial dans la langue, sauf pour la compatibilité. Il casse beaucoup de programmes, de manière très subtile.
- Quels sont les inconvénients, sauf pour la compatibilité?- Outre la compatibilité, l'inconvénient est que nous aurions besoin de deux nouvelles opérations, deux nouvelles fonctions. Comme «supprimer la clé», car affecter nil ne supprimerait pas la clé, nous aurions donc une sorte d'opération primitive pour supprimer la clé et la supprimer vraiment de la table. Et 'test' pour vérifier où distinguer exactement entre zéro et absent. Nous avons donc besoin de deux fonctions primitives.
- Avez-vous analysé l'impact de cela sur des implémentations réelles?- Oui, nous avons sorti une version de Lua avec ça. Et comme je l'ai dit, cela casse le code de nombreuses manières subtiles. Il y a des gens qui font table.insert (f (x)) - un appel à une fonction. Et c'est exprès, c'est par conception que lorsqu'une fonction ne veut rien insérer, elle retourne nil. Donc au lieu d'une coche distincte "est-ce que je veux insérer?", Alors j'appelle un table.insert, et sachant que s'il est nul, il ne sera pas inséré. Comme tout dans chaque langue, un bogue devient une fonctionnalité, et les gens utilisent la fonctionnalité - mais si vous la changez, vous cassez le code.
- Et un nouveau type de vide? Comme nul, mais nul?- Oh non, c'est un cauchemar. Vous venez de reporter le problème, si vous en mettez un autre, alors vous en avez besoin d'un autre et d'un autre et d'un autre. Ce n'est pas la solution. Le principal problème - enfin, pas le principal, mais l'un des problèmes - est que zéro est déjà ancré dans de nombreux endroits de la langue. Par exemple, un exemple très typique. Nous disons: vous devez éviter les nils dans les tableaux, les trous. Mais ensuite, nous avons des fonctions qui renvoient nil et quelque chose après nil, nous obtenons donc un code d'erreur. Donc, cette construction elle-même suppose ce que nil représente ... Par exemple, si je veux faire une liste des retours de cette fonction, juste pour capturer tous ces retours.
- C'est pourquoi vous avez un hack pour ça. :)- Exactement, mais vous n'avez pas besoin d'utiliser des hacks pour un problème aussi primitif et évident. Mais la façon dont les bibliothèques sont construites ... J'y ai déjà pensé - peut-être que les bibliothèques devraient retourner false au lieu de nil - mais c'est une solution à moitié cuite, elle ne résout qu'une petite partie du problème. Le vrai problème, comme je l'ai dit, est que nous devrions avoir zéro dans les tableaux. Sinon, nous ne devrions peut-être pas utiliser nils aussi souvent que nous le faisons actuellement. C'est un peu désordonné. Donc, si vous créez un void, ces fonctions renverraient toujours un nil, et nous aurions toujours ce problème à moins que nous ne créons un nouveau type et les fonctions renverraient void au lieu de nil.
- Void pourrait être utilisé pour indiquer explicitement que la clé doit être conservée dans une table - clé avec une valeur nulle. Et rien ne peut agir comme avant.- Oui, c'est ce que je veux dire. Toutes les fonctions des bibliothèques doivent renvoyer void ou nil.
- Ils peuvent toujours retourner nul, pourquoi pas?- Parce que nous aurions toujours le problème de ne pas pouvoir capturer certaines fonctions.
- Mais il n'y aura pas de première clé, seulement une deuxième clé.- Non, il n'y aura pas de deuxième clé, car le comptage sera erroné et vous aurez un trou dans le tableau.
- Oui, alors tu dis que tu as besoin d'une fausse métaméthode?- Oui. Mon rêve est quelque chose comme ça:
{f(x)}
Vous devez capturer tous les retours de la fonction
f(x)
. Et puis je peux faire
%x
ou
#x
, et cela me donnera le nombre de retours de la fonction. C'est ce qu'un langage raisonnable devrait faire. Donc, créer un vide ne résoudra pas cela, à moins d'avoir une règle très stricte selon laquelle les fonctions ne doivent jamais retourner nulles, mais alors pourquoi avons-nous besoin de zéro? Nous devrions peut-être l'éviter.
- Roberto, y aura-t-il un support d'analyse statique beaucoup plus fort pour Lua? Comme "Lua Check on steroids." Je sais que cela ne résoudra pas tous les problèmes, bien sûr. Vous dites que c'est une fonctionnalité pour 6.0, si jamais, non? Donc, si dans un 5.x il y aura un outil d'analyse statique puissant - si des heures et des années-homme étaient investies - cela aiderait-il vraiment?- Non, je pense qu'un outil d'analyse statique vraiment puissant s'appelle ... système de type! Si vous voulez un outil vraiment puissant, vous devez utiliser un langage typé statiquement, quelque chose comme Haskell ou même quelque chose avec des types dépendants. Ensuite, vous aurez des outils d'analyse vraiment puissants.
- Mais tu n'as pas Lua.- Exactement, Lua est pour ...
- Imprécis? J'ai vraiment apprécié votre photo de girafe sur les types statiques et dynamiques.- Oui, ma dernière diapositive.
La dernière diapositive du discours de Roberto Ierusalimschy "Pourquoi (et pourquoi pas) Lua?"
à la conférence Lua à Moscou 2019- Pour notre prochaine question préparée, revenons à cette image. Si je comprends bien, votre position est que Lua est un petit outil pratique et pratique pour résoudre des tâches pas très importantes.- Non, je pense que vous pouvez faire de grandes tâches, mais pas avec une analyse statique. Je crois fermement aux tests. Soit dit en passant, je ne suis pas d'accord avec vous sur la couverture, votre avis est que nous ne devrions pas poursuivre la couverture ... Je veux dire, je suis entièrement d'accord que la couverture n'implique pas un test complet, mais la non-couverture implique un test de zéro pour cent. J'ai donc parlé d'une salle de test - vous étiez là à Stockholm. J'ai donc commencé mon test avec [quelques] bugs - c'est la chose la plus étrange - l'un d'eux était célèbre, l'autre était complètement non célèbre. C'est quelque chose de complètement cassé dans un fichier d'en-tête de Microsoft, C et C ++. Je recherche donc sur le Web et personne ne s'en soucie ni ne le remarque.
Par exemple, il existe une fonction mathématique,
modf () , où vous devez passer un pointeur sur un double car il renvoie deux doubles. Nous traduisons la partie entière du nombre ou la partie fractionnaire. Cela fait donc longtemps partie d'une bibliothèque standard. Puis est venu C 99, et vous avez besoin de cette fonction pour les flotteurs. Et le fichier d'en-tête de Microsoft a simplement conservé cette fonction et en a déclaré une autre en tant que macro. Donc, il a mis celui-ci en caractères de type. Donc, il a jeté le double pour flotter, ok, puis il a jeté le pointeur pour doubler pour que le pointeur flotte!
- Quelque chose ne va pas sur cette image.- Il s'agit d'un fichier d'en-tête de Visual C ++ et Visual C 2007. Je veux dire, si vous avez appelé cette fonction une fois, avec tous les paramètres, et vérifié les résultats - ce serait faux à moins que ce ne soit zéro. Sinon, toute autre valeur sera erronée. Vous n'utiliseriez jamais cette fonction. Couverture zéro. Et puis il y a beaucoup de discussions sur les tests ... Je veux dire, appelez simplement une fonction une fois, vérifiez les résultats! Donc ça y est, ça y est depuis longtemps, depuis de nombreuses années personne ne s'en souciait. Un très célèbre était à Apple.
Quelque chose comme "
if… what… goto… ok
", c'était quelque chose comme ça. Quelqu'un a mis une autre déclaration ici. Et puis tout allait bien. Et il y a eu beaucoup de discussions que vous devriez avoir les règles, les crochets devraient être obligatoires dans votre style, etc., etc. Personne n'a mentionné qu'il y avait beaucoup d'autres ifs ici. Cela n'a jamais été exécuté ...
- Il y a aussi un problème de sécurité pour autant que je m'en souvienne.- Oui, exactement. Parce qu'ils testaient seulement des cas approuvés. Ils ne testaient rien, car tout serait approuvé. Cela signifie qu'il n'y a pas un seul cas de test dans l'application de sécurité qui vérifie si elle refuse une connexion ou quoi que ce soit qu'elle devrait refuser. Alors tout le monde discute et dit qu'ils devraient avoir des crochets ... Ils devraient avoir des tests, des tests minimum! Parce que personne n'a jamais testé cela, c'est ce que je veux dire par couverture. C'est incroyable de voir comment les gens ne font pas de tests de base. Parce que s'ils faisaient tous les tests de base, alors bien sûr, c'est un cauchemar de faire toute la couverture et d'exécuter toutes les lignes, etc. Les gens négligent même les tests de base, la couverture est donc au moins à peu près minimale. C'est une façon d'attirer l'attention sur certaines parties du programme que vous avez oubliées. C'est une sorte de guide pour améliorer un peu vos tests.
- Quelle est la couverture des tests dans Tarantool? 83%! Roberto, quelle est la couverture du test Lua?- Environ 99,6. Combien de lignes de code avez-vous? Un million, des centaines de milliers? Ce sont des nombres énormes. Un pour cent de cent mille, c'est mille lignes de code qui n'ont jamais été testées. Vous ne l'avez pas exécuté du tout. Vos utilisateurs ne testent rien.
- Il y a donc 17% des fonctionnalités de Tarantool qui ne sont pas utilisées actuellement?- Je ne sais pas si vous voulez tout décompresser où nous en étions ... Je pense que l'un des problèmes avec les langages dynamiques (et les langages statiques d'ailleurs) est que les gens ne testent pas les trucs. Même si vous avez un langage statique, à moins que vous n'ayez quelque chose - pas même comme Haskell, mais Coq, - un système de preuve, vous changez cela pour ceci ou cela. Aucun outil d'analyse statique ne peut détecter ces erreurs, vous avez donc besoin de tests. Et si vous avez les tests, vous détectez des problèmes globaux, renommez les fautes d'orthographe, etc. Tous ces types d'erreurs. Vous devriez avoir ces tests de toute façon, peut-être que parfois c'est un peu plus difficile à déboguer, parfois ce n'est pas le cas - cela dépend de la langue et du type de bogue. Mais le problème est qu'aucun outil d'analyse statique ne peut vous permettre d'éviter les tests. Les tests, par contre ... eh bien, ils ne prouvent jamais l'absence d'erreur, mais je me sens beaucoup plus en sécurité après tous les tests.
- Nous avons une question sur le test des modules Lua. En tant que développeur, je souhaite tester certaines fonctions locales qui pourront être utilisées ultérieurement. La question est: nous voulons avoir une couverture d'environ 99%, mais pour l'API produite par ce module, le nombre de cas fonctionnels qu'il devrait produire est bien inférieur à la fonctionnalité qu'il prend en charge en interne.- Pourquoi ça, désolé?
- Certaines fonctionnalités ne sont pas accessibles par l'interface publique.- S'il y a une fonctionnalité qui n'est pas accessible par l'interface publique, elle ne devrait pas être là, effacez-la. Effacez ce code.
- Tue-le?- Oui, parfois je fais ça à Lua. Il y avait une certaine couverture de code, je ne pouvais pas y arriver ou là ou là, alors j'ai pensé que c'était impossible et j'ai simplement supprimé le code. Ce n'est pas si courant, mais c'est arrivé plus d'une fois. Ces cas étaient impossibles à se produire, vous venez de mettre une affirmation pour expliquer pourquoi cela ne peut pas se produire. Si vous ne pouvez pas accéder à vos fonctions à partir de l'API publique, elle ne devrait pas y être. Nous devons coder l'API publique avec une entrée incorrecte, ce qui est essentiel pour les tests.
- Supprimez le code, la suppression est bonne, elle réduit la complexité. Une complexité réduite augmente la maintenabilité et la stabilité. Restez simple.- Oui, la programmation extrême avait cette règle. Si ce n'est pas dans un test, alors il n'existe pas.
- Quelles langues vous ont inspiré lorsque vous avez créé Lua? Quels paradigmes ou spécialités fonctionnelles ou parties de ces langues avez-vous aimé?- J'ai conçu Lua dans un but très précis, ce n'était pas un projet académique. C'est pourquoi quand vous me demandez si je le recréerais, je dis qu'il y a beaucoup de trucs historiques sur la langue. Je n'ai pas commencé par 'Laissez-moi créer le langage que je veux ou veux utiliser ou tout le monde a besoin etc. Mon problème était «Ce programme a besoin ici d'un langage de configuration pour les géologues et les ingénieurs, et j'ai besoin de créer un petit langage qu'ils pourraient utiliser avec une interface facile. C'est pourquoi l'API a toujours fait partie intégrante du langage, car il est plus facile à intégrer. C'était le but. Ce que j'avais dans mon passé, c'est beaucoup de langues différentes à l'époque ... une dizaine. Si vous voulez tout l'arrière-plan ...
- Je m'intéressais aux langues que vous vouliez inclure dans Lua.- Je recevais des choses de plusieurs langues différentes, quel que soit le problème que je rencontrais. La plus grande inspiration était le langage Modula pour la syntaxe, mais sinon, c'est difficile à dire car il y a tellement de langues. Certaines choses venaient d'AWK, c'était une autre petite inspiration. Bien sûr, Scheme et Lisp ... J'ai toujours été fasciné par Lisp depuis que j'ai commencé à programmer.
- Et toujours pas de macros à Lua!- Oui, il y a beaucoup de différence de syntaxe. Fortran, je pense, était la première langue ... non, la première langue que j'ai apprise était l'assemblage, puis est venu le fortran. J'ai étudié, mais je n'ai jamais utilisé CLU. J'ai fait beaucoup de programmation avec Smalltalk, SNOBOL. J'ai aussi étudié, mais je n'ai jamais utilisé Icon, c'est aussi très intéressant. Beaucoup venaient de Pascal et C. Au moment où j'ai créé Lua, le C ++ était déjà trop complexe pour moi - et c'était avant les modèles, etc. C'était en 1991, et en 1993, Lua a commencé.
- L'Union soviétique est tombée et vous avez commencé à créer Lua. :) Vous ennuyiez-vous avec des points-virgules et des objets lorsque vous avez commencé à travailler sur Lua? Je m'attendrais à ce que Lua ait une syntaxe similaire à C, car il est intégré à C. Mais ...- Oui, je pense que c'est une bonne raison de ne pas avoir de syntaxe similaire - donc vous ne les mélangez pas, ce sont deux langues différentes.
C'est quelque chose de vraiment drôle et c'est lié à la réponse que vous ne m'avez pas permis [à la conférence] de donner sur des tableaux à partir de 1. Ma réponse était trop longue.
Quand nous avons commencé Lua, le monde était différent, tout n'était pas comme C. Java et JavaScript n'existaient pas, Python en était à ses balbutiements et avait une version inférieure à 1.0. Il n'y avait donc pas cette chose quand tous les langages sont censés être en C. C n'était qu'une des nombreuses syntaxes disponibles.
Et les tableaux étaient exactement les mêmes. C'est très drôle que la plupart des gens ne s'en rendent pas compte. Il y a de bonnes choses à propos des tableaux à base zéro ainsi que des tableaux à base unique.
Le fait est que la plupart des langages populaires sont basés sur zéro à cause de C. Ils étaient en quelque sorte inspirés par C. Et le plus drôle est que C n'a pas d'indexation. Vous ne pouvez donc pas dire que les index C sont des tableaux à partir de zéro, car il n'y a pas d'opération d'indexation. C a une arithmétique de pointeur, donc zéro en C n'est pas un index, c'est un décalage. Et en tant que décalage, ce doit être un zéro - pas parce qu'il a de meilleures propriétés mathématiques ou parce qu'il est plus naturel, peu importe.
Et tous ces langages qui ont copié C, ils ont des index et n'ont pas d'arithmétique de pointeur. Java, JavaScript, etc., etc. - aucun d'eux n'a d'arithmétique de pointeur. Ils ont donc simplement copié le zéro, mais c'est une opération complètement différente. Ils ont mis zéro pour aucune raison - c'est comme un culte du fret.
- Vous dites que c'est logique si vous avez un langage intégré en C pour le faire avec une syntaxe de type C. Mais si vous avez un langage C-embarqué, je suppose que vous avez des programmeurs C qui veulent que le code soit en C et pas un autre langage, qui ressemble à C, mais pas C. Donc, les utilisateurs de Lua n'ont jamais été censés utiliser C tous les jours? Pourquoi?- Qui utilise C tous les jours?
- Programmeurs système.- Exactement. C'est le problème, trop de gens utilisent C, mais ne devraient pas être autorisés à l'utiliser. Les programmeurs doivent être certifiés pour utiliser C. Pourquoi le logiciel est-il si cassé? Tous ces hacks envahissant le monde, tous ces problèmes de sécurité. La moitié au moins est due à C. Il est vraiment difficile de programmer en C.
- Mais Lua est en C.- Oui, et c'est ainsi que nous avons appris à quel point il est difficile de programmer en C. Vous avez des débordements de tampon, vous avez des débordements d'entier qui provoquent des débordements de tampon ... Il suffit d'obtenir un seul programme C que vous pouvez être sûr qu'aucune arithmétique ne va mal si les gens mettent n'importe quel nombre n'importe où et tout est vérifié. Là encore, de vrais problèmes de portabilité - peut-être que parfois, dans un processeur, cela fonctionne, mais cela arrive à l'autre processeur ... C'est fou.
Par exemple, très récemment, nous avons eu un problème. Comment savez-vous que votre programme C ne fait pas de débordement de pile? Je veux dire la profondeur de pile, pas le débordement de pile parce que vous avez envahi ... Combien d'appels avez-vous le droit de faire dans un programme C?
- Dépend de la taille d'une pile.- Exactement. Que dit la norme à ce sujet? Si vous codez en C et puis vous faites cette fonction qui appelle cette fonction qui appelle cette fonction ... combien d'appels pouvez-vous faire?
- 16 mille?- Je me trompe peut-être, mais je pense que la norme ne dit rien à ce sujet.
- Je pense qu'il n'y a rien dans la norme car elle dépend trop de la taille.- Bien sûr, cela dépend de la taille de chaque fonction. Il peut s'agir d'énormes tableaux automatiques dans le cadre des fonctions ... Donc, la norme ne dit rien et il n'y a aucun moyen de vérifier si un appel sera valide. Vous pouvez donc avoir un seul problème si vous avez des appels en trois étapes, il peut se bloquer et être toujours un programme C valide. Correct selon la norme - bien qu'il ne soit pas correct car il se bloque. Il est donc très difficile de programmer en C, car il y en a tellement ... Un autre bon exemple: quel est le résultat lorsque vous soustrayez deux pointeurs? Personne ici ne travaille avec C?
- Non, alors ne les grille pas. Mais C ++ prend en charge différents types.- Non, C ++ a le même problème.
- Quel est le type de déclaration? ptrdiff_t
?- Exactement,
ptrdiff_t
est un type signé. Donc, généralement, si vous avez une mémoire standard de la taille de votre mot et que vous soustrayez deux pointeurs dans cet espace, vous ne pouvez pas représenter toutes les tailles dans le type signé. Alors, que dit la norme à ce sujet?
Lorsque vous soustrayez deux pointeurs, si la réponse tient dans un diff de pointeur, c'est la réponse. Sinon, vous avez un comportement indéfini. Et comment savoir si cela convient? Non. Donc, chaque fois que vous soustrayez deux pointeurs, vous savez généralement que ce n'est pas standard, que si vous pointez sur quelque chose de plus grand qu'au moins 2 octets, alors la plus grande taille serait la moitié de la taille de la mémoire, donc tout va bien.
Vous ne rencontrez donc un problème que si vous pointez sur des octets ou des caractères. Mais lorsque vous faites cela, vous avez un vrai problème, vous ne pouvez pas faire de l'arithmétique du pointeur sans vous soucier d'avoir une chaîne plus grande que la moitié de la mémoire. Et puis je ne peux pas simplement calculer la taille et stocker dans un type de pointeur diff car c'est faux.
C'est ce que je veux dire à propos d'un programme C ou C ++ sécurisé qui est vraiment sûr.
- Avez-vous envisagé d'implémenter Lua dans une autre langue? Le changer de C à autre chose?- Lorsque nous avons commencé, j'ai envisagé le C ++, mais comme je l'ai dit, j'ai abandonné son utilisation en raison de la complexité - Je ne peux pas apprendre tout le langage. Il devrait être utile d'avoir des trucs en C ++ mais ... même aujourd'hui, je ne vois aucun langage qui ferait l'affaire.
- Pouvez-vous expliquer pourquoi?- Parce que je n'ai pas d'alternative. Je peux seulement expliquer pourquoi contre d'autres langues. Je ne dis pas que C est parfait ou même bon, mais c'est le meilleur. Pour expliquer pourquoi, je dois le comparer avec d'autres langues.
- Et JVM?- Oh, JVM. Allez, il ne tient pas dans la moitié du matériel ... La portabilité est la principale raison, mais aussi les performances. Dans JVM, c'est un peu mieux que .NET, mais ce n'est pas si différent. Beaucoup de choses que Lua fait nous ne pouvons pas faire avec JVM. Vous ne pouvez pas contrôler le garbage collector par exemple. Vous devez utiliser le garbage collector JVM car vous ne pouvez pas avoir un autre garbage collector implémenté au-dessus de JVM. JVM est également un grand consommateur de mémoire. Quand un programme Java commence à dire bonjour, c'est comme 10 Mo environ. La portabilité est un problème non pas parce qu'elle n'a pas été portée, mais parce qu'elle ne peut pas l'être.
- Qu'en est-il des modifications JVM comme Mobile JVM?- Ce n'est pas JVM, c'est une blague. C'est comme une micro édition de Java, pas Java.
- Et les autres langages statiques comme Go ou Oberon? Pourraient-ils être la base de Lua si vous l'avez créé aujourd'hui?- Oberon ... peut-être, ça dépend ... Allez, encore une fois, a un ramasse-miettes et a un temps d'exécution trop grand pour Lua. Oberon serait une option, mais Oberon a des choses très étranges, comme vous n'avez presque pas de constantes, si je me souviens bien. Oui, je pense qu'ils ont supprimé const de Pascal à Oberon. J'avais un livre sur Oberon et j'ai adoré Oberon. Son
système était incroyable, c'est vraiment quelque chose.
Je me souviens qu'en 1994, j'ai vu une démonstration d'Oberon et de Self. Vous connaissez-vous? C'est un langage dynamique très intéressant avec des compilateurs jit etc ... J'ai vu ces démos à une semaine d'intervalle, et Self était très intelligent, ils ont utilisé certaines techniques de dessins animés pour masquer la lenteur des opérations. Parce que quand vous avez ouvert quelque chose, c'était comme "woop!" - d'abord, il diminue un peu, puis se développe avec quelques effets. Il a été très bien implémenté, ces techniques qu'ils ont utilisées pour simuler le mouvement ...
Puis une semaine plus tard, nous avons vu une démo d'Oberon, il fonctionnait comme 1/10
e de matériel pour Self - il y avait cette très vieille petite machine. À Oberon, vous cliquez puis vous bougez, tout fonctionne immédiatement, tout le système était si léger.
Mais pour moi, c'est trop minimaliste, ils ont supprimé les constantes et les types de variantes.
- Haskell?- Je ne connais pas Haskell ni comment implémenter Lua dans Haskell.
- Et quelle est votre attitude vis-à-vis des langages comme Python ou R ou Julia comme base pour les futures implémentations de Lua?- Je pense que chacun d'eux a ses utilisations.
R semble être bon pour les statistiques. C'est très spécifique au domaine, fait par des gens de la région, c'est donc une force.
Python est bien, mais j'ai eu des problèmes personnels avec. Je pensais l'avoir mentionné dans mon discours ou dans l'interview. Cette chose de ne pas connaître la langue entière ou de ne pas l'utiliser, l'erreur de sous-ensemble.
Nous utilisons Python dans nos cours, en enseignant la programmation de base - juste une petite partie, des boucles et des entiers. Tout le monde était content, puis ils ont dit que ce serait bien d'avoir des applications graphiques, donc nous avions besoin d'une bibliothèque graphique. Et presque toutes les bibliothèques graphiques, vous obtenez l'API ... Mais je ne connais pas assez Python, c'est un truc très avancé. Il a l'illusion que c'est facile et j'ai toutes ces bibliothèques pour tout, mais c'est facile ou vous avez tout.
Donc, quand vous commencez à utiliser la langue, alors vous commencez: oh, je dois apprendre la POO, l'héritage, quoi que ce soit d'autre. Chaque bibliothèque. Il semble que les auteurs soient fiers d'utiliser des fonctionnalités de langage plus avancées dans leur API pour montrer que je ne sais pas quoi. Appels de fonction, types standard, etc. Vous avez cet objet, puis si vous voulez autre chose, vous devez créer un autre objet ...
Même la correspondance de motifs, vous pouvez faire des choses simples, mais généralement la correspondance de motifs standard n'est pas quelque chose que vous faites. Vous effectuez une correspondance, un objet renvoie un résultat, puis vous appelez des méthodes sur ce résultat d'objet pour obtenir le résultat réel de la correspondance. Parfois, il existe un moyen plus simple à utiliser, mais ce n'est pas évident, ce n'est pas la façon dont la plupart des gens utilisent.
Un autre exemple: j'enseignais un cours sur la correspondance de motifs et je voulais utiliser la syntaxe de type Perl, et je ne pouvais pas utiliser Lua à cause d'une syntaxe complètement différente. J'ai donc pensé que Python serait l'exemple parfait. Mais en Python, il existe des fonctions directes pour certaines choses de base, mais pour tout ce qui est plus complexe, vous devez connaître les objets et les méthodes, etc. Je voulais juste faire quelque chose et avoir le résultat.
- Qu'avez-vous fini par utiliser?- J'ai utilisé Python et leur ai expliqué. Mais même Perl est beaucoup plus simple, vous faites le match et les résultats sont de 1 $, 2 $, 3 $, c'est beaucoup plus facile, mais je n'ai pas le courage d'utiliser Perl, alors ...
- J'utilisais Python depuis deux ans avant de remarquer qu'il y avait des décorateurs. (question de Yaroslav Dynnikov de l'équipe Tarantool)- Oui, et lorsque vous souhaitez utiliser une bibliothèque, vous devez apprendre ce genre de choses et vous ne comprenez pas l'API, etc. Python donne l'illusion que c'est facile mais c'est assez complexe.
... Et Julia, je ne connais pas grand-chose à Julia, mais cela m'a rappelé LuaJIT dans le sens où cela ressemble parfois à la fierté de l'utilisateur. Vous pouvez avoir de très bons résultats, mais vous devez vraiment comprendre ce qui se passe. Ce n'est pas comme si vous écriviez du code et obteniez de bons résultats. Non, vous écrivez du code et parfois les résultats sont bons, parfois ils sont horribles. Et lorsque les résultats sont horribles, vous avez beaucoup de bons outils qui vous montrent le langage intermédiaire qui a été généré une fois, vous le vérifiez et ensuite vous parcourez tout ce code presque assembleur. Ensuite, vous vous rendez compte: oh, ce n'est pas l'optimisation à cause de cela. C'est le problème des programmeurs, ils aiment les jeux et parfois ils aiment les trucs parce que c'est difficile, pas parce que c'est facile.
Je ne sais pas grand chose sur Julia, mais j'ai vu une fois en parler. Et le gars qui parlait, c'était lui qui avait ce point de vue: voyez comme c'est sympa, nous avons écrit ce programme et c'est parfait. Je ne me souviens pas de grand chose, quelque chose sur la multiplication matricielle je suppose. Et puis les flotteurs sont parfaits, puis les doubles sont parfaits, et ensuite ils mettent des [nombres] complexes ... et ce fut une tragédie. Comme cent fois plus lentement.
(sarcastique) «Voyez comme c'est agréable, nous avons cet outil, nous pouvons voir l'ensemble de l'assemblage [listage], et ensuite vous allez changer cela et cela et cela. Voyez à quel point c'est efficace ». Oui, je vois, je peux programmer directement en assembleur.
Mais ce n'était qu'un discours. J'ai étudié un peu de R et j'ai une certaine expérience utilisateur avec Python pour les petites choses.
- Que pensez-vous d'Erlang?- Erlang est une langue amusante. Il a de très bonnes utilisations, la tolérance aux pannes est vraiment intéressante. Mais ils prétendent que c'est un langage fonctionnel et l'idée du langage fonctionnel est que vous n'avez pas d'état.
Et Erlang a un énorme état caché dans les messages envoyés et non encore reçus. Donc, chaque petit processus est complètement fonctionnel mais le programme lui-même est complètement non fonctionnel.
C'est un gâchis de données cachées qui est bien pire que les variables globales car s'il s'agissait de variables globales, vous les imprimeriez. Messages qui sont l'état réel de votre système. À chaque instant, quel est l'état du système? Il y a tous ces messages envoyés ici et là. C'est complètement non fonctionnel, du tout.
- Erlang ment donc sur la fonctionnalité et Python sur la simplicité. Sur quoi ment Lua?- Lua ment un peu sur sa petite taille. C'est encore plus petit que la plupart des autres langues, mais si vous voulez une très petite langue, alors Lua est plus grande que vous ne le souhaitez.
- Qu'est-ce qu'une petite langue alors?- Forth est, j'aime Forth.
- Y a-t-il une place pour une version plus petite de Lua?- Peut-être, mais c'est difficile. J'adore les tables mais les tables ne sont pas très petites. Si vous voulez représenter de petites choses, l'idée derrière les tables ne vous conviendra pas. Ce serait la syntaxe de Lua, nous l'appellerions Lua mais ce n'est pas Lua.
Ce serait comme la micro édition Java. Vous l'appelez Java mais a-t-il du multi-threading? Non, non. At-il une réflexion? Non, non. Alors pourquoi l'utiliser? Il a une syntaxe de Java, le même type de système mais ce n'est pas du tout Java. C'est un langage différent qui est plus facile à apprendre si vous connaissez Java mais ce n'est pas Java.
Si vous voulez faire un petit langage qui ressemble à Lua mais Lua sans tables ne l'est pas ... Vous devriez probablement avoir à déclarer des tables, quelque chose comme FFI pour pouvoir être petit.
- Y a-t-il des adaptations plus petites de Lua?- Peut-être, je ne sais pas.
- Lua est-il prêt pour une programmation fonctionnelle pure? Pouvez-vous le faire avec Lua?- Bien sûr que vous le pouvez. Ce n'est pas particulièrement efficace, mais seul Haskell est vraiment efficace pour cela. Si vous commencez à utiliser des monades et des trucs comme ça, créez de nouvelles fonctions, composez des fonctions etc ... Vous pouvez le faire avec Lua, cela fonctionne assez raisonnablement, mais vous avez besoin de techniques d'implémentation différentes des langages impératifs normaux pour faire quelque chose de vraiment efficace.
— Actually, there is a library for functional programming in Lua.— Yes, it's reasonable and usable, if you do really need performance; you can do a lot of stuff with it. I love functional stuff and I do it all the time.
— My question is more about the garbage collector, because we only have only mutable objects and we have to use them efficiently. Will Lua be good for that?— I think a new incarnation of garbage collector will help a lot, but again…
— Young die young? The one that seems to work with young objects?— Exactly, yes. But as I said even with the standard garbage collector we don't have optimal performance but it can be reasonable. More often you don't even need that performance for most actions unless you are writing servers and having big operations.
— What functional programming tasks do you perform in Lua?— A simple example. My book, I'm writing my own format and I have a formatter that transforms that in LaTex or DocBook. It's completely functional, it has a big pattern matching… It's slightly inspired by LaTex but much more uniformed. There's @ symbol instead of backslash, a name of a macro and one single argument in curly brackets. So I have gsub that recognizes this kind of stuff and then it calls a function, the function does something and returns something. It's all functional, just functions on top of functions on top of functions, and the final function gives a big result.
— Why don't you program with LaTeX?— Plain LaTeX? First, it's too tricky for a lot of stuff and so difficult. I have several things that I don't know how to do in LaTex. For example, I want to put a piece of inline code inside a text. Then there is a slash verb, standard stuff. But slash verb gives fixed space. And the space between stuff is never right. All real spaces are variable, it depends on how the line is adjusted, so it expands in some spaces and compacts in others depending on a lot of stuff. And those spaces are fixed, so sometimes they look too large, sometimes too small. It also depends on what you put in code.
— But you still render your own format to LaTeX?— Yes, but with a lot of preprocessing. I write my own verb but then it changes and becomes not a verb but a lot of stuff. For example, when I write 3+1 I write a very small space here. In verb, if I don't put any space here, it shrinks, and if I do, it's too large. So I do the preprocessing, inserting a variable space. It's very small but can be a little larger if it needs to adjust. But if I put 'and' after 1 then I put a larger space. This function here does all that. This is a small example but there are other things…
— Do you have a source?— I do have the source, it is in the
git . The program's called
2html . The current version only generates HTML… Sorry, that's a kind of a mess. I created it for a book but also another one for the manual. The one in the git is for the manual. But the other one is more complicated and not public, I can't make it public. But the main problem is that TeX is not there. It's almost impossible to process TeX files without TeX itself.
— Is it not machine-readable?— Yes, it's not machine-readable. I mean, it is readable because TeX reads it. It's so hard to test, so many strange rules etc. So this is much more uniformed and as I said I generate DocBook format, sometimes I need it. That started when I had this contract for a book.
— So you use 2html to generate DocBook?— Yes, it generates DocBook directly.
— Ok, thank you very much for the interview!
If you have any more questions, you can ask them in the
Lua Mailing List . See you soon!