Lua in Moskau 2019: Interview mit Roberto Ierusalimschy



Vor einiger Zeit besuchte der Schöpfer der Programmiersprache Lua, Roberto Ierusalimschy, unser Moskauer Büro. Wir haben ihm einige Fragen gestellt, die wir unter Beteiligung von Habr.com-Nutzern vorbereitet haben. Und schließlich möchten wir die Volltextversion dieses Interviews teilen.

- Beginnen wir mit einigen philosophischen Fragen. Stellen Sie sich vor, wenn Sie Lua von Grund auf neu erstellen würden, welche drei Dinge würden Sie in Lua ändern?

- Wow! Das ist eine schwierige Frage. In die Schaffung und Entwicklung der Sprache ist so viel Geschichte eingebettet. Es war keine große Entscheidung auf einmal. Es gibt einige Bedauern, von denen ich einige im Laufe der Jahre korrigieren konnte. Die Leute beschweren sich ständig darüber wegen der Kompatibilität. Wir haben es mehrmals gemacht. Ich denke nur an kleine Dinge.

- Standardmäßig global? Glaubst du, das ist der Weg?

- Vielleicht. Für dynamische Sprachen ist es jedoch sehr schwierig. Vielleicht besteht die Lösung darin, überhaupt keine Standardeinstellungen zu haben, aber dann wäre es schwierig, Variablen zu verwenden.

Zum Beispiel müssten Sie irgendwie alle Standardbibliotheken deklarieren. Sie möchten einen Einzeiler, print(sin(x)) , und dann müssen Sie 'print' und auch 'sin' deklarieren. Es ist also seltsam, Erklärungen für diese Art von sehr kurzen Skripten zu haben.

Alles, was größer ist, sollte keine Standardeinstellungen haben, denke ich. Standardmäßig ist Local nicht die Lösung, es existiert nicht. Es ist nur für Aufgaben, nicht für die Verwendung. Etwas, das wir zuweisen und dann verwenden und dann zuweisen, und es gibt einen Fehler - völlig mystifizierend.

Möglicherweise ist global standardmäßig nicht perfekt, aber lokal standardmäßig ist dies keine Lösung. Ich denke, eine Art Erklärung, vielleicht eine optionale Erklärung ... Wir hatten diesen Vorschlag oft - eine Art globale Erklärung. Aber am Ende denke ich, dass das Problem darin besteht, dass die Leute immer mehr nachfragen und wir aufgeben.

(sarkastisch) Ja, wir werden eine globale Erklärung abgeben - fügen Sie das und das und das hinzu, setzen Sie das aus, und am Ende verstehen wir, dass die endgültige Schlussfolgerung die meisten Menschen nicht zufriedenstellen wird und wir nicht alle Optionen aufstellen werden, die jeder will. Also setzen wir nichts. Am Ende ist der strikte Modus ein vernünftiger Kompromiss.

Es gibt dieses Problem: Meistens verwenden wir beispielsweise Felder innerhalb der Module, dann haben Sie wieder dieselben Probleme. Es ist nur ein sehr spezifischer Fall von Fehlern, den die allgemeine Lösung wahrscheinlich beinhalten sollte. Ich denke, wenn Sie das wirklich wollen, sollten Sie eine statisch typisierte Sprache verwenden.

- Standardmäßig ist Global auch für kleine Konfigurationsdateien geeignet.

- Ja genau für kleine Skripte und so weiter.

- Keine Kompromisse hier?

- Nein, es gibt immer Kompromisse. Es gibt einen Kompromiss zwischen kleinen Skripten und echten Programmen oder so etwas.

- Wir kommen also auf die erste große Frage zurück: Drei Dinge, die Sie ändern würden, wenn Sie die Chance hätten. Aus meiner Sicht sind Sie ziemlich zufrieden mit dem, was wir jetzt haben, stimmt das?

- Nun, es ist keine große Veränderung, aber dennoch ... Unsere Forderungsausfälle, die zu einer großen Veränderung wurden, sind Nullen in Tabellen. Das bereue ich wirklich. Ich habe diese Art von Implementierung gemacht, eine Art Hack ... Hast du gesehen, was ich getan habe? Ich habe vor ungefähr sechs Monaten oder einem Jahr eine Version von Lua geschickt, die keine Tabellen enthält.

- Nullwerte?

- Genau. Ich denke, es wurde in Tabellen nils genannt - was null heißt. Wir haben die Grammatik etwas gehackt, um sie einigermaßen kompatibel zu machen.

- Warum wird es benötigt?

- Ich bin wirklich davon überzeugt, dass dies ein ganzes Problem von Löchern ist ... Ich denke, dass die meisten Probleme von Nullen in Arrays verschwinden würden, wenn wir [Nullen in Tabellen] haben könnten ... Weil das genaue Problem nicht Nullen in Arrays ist. Die Leute sagen, wir können keine Nullen in Arrays haben, also sollten wir Arrays von Tabellen getrennt haben. Aber das eigentliche Problem ist, dass wir keine Nullen in Tabellen haben können! Das Problem liegt also bei den Tabellen und nicht bei der Darstellung von Arrays. Wenn wir Nullen in Tabellen haben könnten, dann hätten wir Nullen in Arrays ohne irgendetwas anderes. Das ist etwas, was ich wirklich bedauere, und viele Leute verstehen nicht, wie sich die Dinge ändern würden, wenn Lua Nullen in Tischen zulässt.

- Darf ich Ihnen eine Geschichte über Tarantool erzählen? Wir haben tatsächlich unsere eigene Implementierung von null, die eine CDATA für einen Nullzeiger ist. Wir verwenden es dort, wo Speicherlücken erforderlich sind. Um Positionsargumente zu füllen, wenn wir Fernaufrufe tätigen und so weiter. Aber wir leiden normalerweise darunter, weil CDATA immer in "wahr" konvertiert wird. Nullen in Arrays würden also viele unserer Probleme lösen.

- Ja, ich weiß. Das ist genau mein Punkt - dies würde viele Probleme für viele Menschen lösen, aber es gibt ein großes Problem der Kompatibilität. Wir haben nicht die Energie, eine Version zu veröffentlichen, die so inkompatibel ist, und dann die Community zu brechen und unterschiedliche Dokumentationen für Lua 5 und Lua 6 usw. zu haben. Aber vielleicht werden wir es eines Tages veröffentlichen. Aber es ist eine wirklich große Veränderung. Ich denke, es hätte von Anfang an so sein sollen - wenn es so wäre, wäre es eine triviale Änderung in der Sprache, abgesehen von der Kompatibilität. Es bricht viele Programme auf sehr subtile Weise.

- Was sind die Nachteile außer der Kompatibilität?

- Neben der Kompatibilität besteht der Nachteil darin, dass wir zwei neue Operationen und zwei neue Funktionen benötigen würden. Wie 'Schlüssel löschen', da das Zuweisen von nil den Schlüssel nicht löschen würde, so dass wir eine Art primitive Operation hätten, um den Schlüssel zu löschen und ihn wirklich aus der Tabelle zu entfernen. Und 'Test', um zu überprüfen, wo genau zwischen Null und Abwesenheit zu unterscheiden ist. Wir brauchen also zwei primitive Funktionen.

- Haben Sie die Auswirkungen auf reale Implementierungen analysiert?

- Ja, damit haben wir eine Version von Lua veröffentlicht. Und wie gesagt, es bricht Code auf viele subtile Arten. Es gibt Leute, die table.insert (f (x)) ausführen - einen Aufruf einer Funktion. Und es ist absichtlich so, dass eine Funktion, wenn sie nichts einfügen möchte, null zurückgibt. Anstelle eines separaten Häkchens "Möchte ich einfügen?" Rufe ich dann eine table.insert auf und weiß, dass sie nicht eingefügt wird, wenn sie gleich Null ist. Wie alles in jeder Sprache wird ein Fehler zu einer Funktion, und die Benutzer verwenden die Funktion. Wenn Sie sie jedoch ändern, wird der Code beschädigt.

- Was ist mit einem neuen Leertyp? Wie Null, aber nichtig?

- Oh nein, das ist ein Albtraum. Sie verschieben das Problem einfach, wenn Sie ein anderes setzen, dann brauchen Sie ein anderes und ein anderes und ein anderes. Das ist nicht die Lösung. Das Hauptproblem - nun ja, nicht das Hauptproblem, aber eines der Probleme - ist, dass Null bereits an vielen Stellen in der Sprache verwurzelt ist. Zum Beispiel ein sehr typisches Beispiel. Wir sagen: Sie sollten Nullen in Arrays und Löchern vermeiden. Aber dann haben wir Funktionen, die nil und etwas nach nil zurückgeben, sodass wir einen Fehlercode erhalten. Diese Konstruktion selbst nimmt also an, was Null darstellt ... Wenn ich beispielsweise eine Liste der Rückgaben dieser Funktion erstellen möchte, nur um alle diese Rückgaben zu erfassen.

- Deshalb hast du einen Hack dafür. :) :)

- Genau, aber Sie müssen keine Hacks für so primitive und offensichtliche [Probleme] verwenden. Aber die Art und Weise, wie die Bibliotheken aufgebaut sind ... Ich habe einmal darüber nachgedacht - vielleicht sollten die Bibliotheken false statt null zurückgeben -, aber es ist eine halbherzige Lösung, die nur einen kleinen Teil des Problems löst. Das eigentliche Problem ist, wie gesagt, dass wir Nullen in Tabellen haben sollten. Wenn nicht, sollten wir vielleicht nicht so häufig Nils verwenden wie jetzt. Es ist alles irgendwie chaotisch. Wenn Sie also eine Leere erstellen, geben diese Funktionen immer noch eine Null zurück, und wir haben immer noch dieses Problem, es sei denn, wir erstellen einen neuen Typ und die Funktionen geben eine Leere anstelle von Null zurück.

- Void kann verwendet werden, um explizit anzugeben, dass der Schlüssel in einem Tabellenschlüssel mit einem void-Wert aufbewahrt werden soll. Und nichts kann so handeln wie zuvor.

- Ja, das meine ich. Alle Funktionen in den Bibliotheken sollten void oder nil zurückgeben.

- Sie können immer noch null zurückgeben, warum nicht?

- Weil wir immer noch das Problem haben würden, dass Sie einige Funktionen nicht erfassen können.

- Aber es wird keinen ersten Schlüssel geben, nur einen zweiten Schlüssel.

- Nein, es wird keinen zweiten Schlüssel geben, da die Zählung falsch ist und Sie ein Loch im Array haben.

- Ja, sagen Sie also, dass Sie eine falsche Metamethode benötigen?

- Ja. Mein Traum ist so etwas:

{f(x)}

Sie sollten alle Rückgaben der Funktion f(x) erfassen. Und dann kann ich %x oder #x , und das gibt mir die Anzahl der Rückgaben der Funktion. Das sollte eine vernünftige Sprache tun. Das Erstellen einer Leere wird das also nicht lösen, es sei denn, wir hatten eine sehr starke Regel, dass Funktionen niemals Null zurückgeben sollten, aber warum brauchen wir dann Null? Vielleicht sollten wir es vermeiden.

- Roberto, wird es eine viel stärkere Unterstützung für statische Analysen für Lua geben? Wie "Lua Check auf Steroide." Ich weiß, dass es natürlich nicht alle Probleme lösen wird. Sie sagen, dies ist eine Funktion für 6.0, wenn überhaupt, oder? Wenn es also in einem 5.x ein starkes statisches Analysetool geben würde - wenn Mannstunden und Mannjahre investiert würden - würde es wirklich helfen?

- Nein, ich denke, ein wirklich starkes statisches Analysewerkzeug heißt ... Typsystem! Wenn Sie ein wirklich starkes Werkzeug wünschen, sollten Sie eine statisch typisierte Sprache verwenden, etwa Haskell oder sogar etwas mit abhängigen Typen. Dann haben Sie wirklich starke Analysewerkzeuge.

- Aber dann hast du Lua nicht.

- Genau, Lua ist für ...

- Ungenau? Ich habe Ihr Giraffenbild auf statischen und dynamischen Typen wirklich genossen.

- Ja, meine letzte Folie.


Die letzte Folie aus Roberto Ierusalimschys Vortrag "Warum (und warum nicht) Lua?"
auf der Konferenz Lua in Moskau 2019

- Kehren wir für unsere nächste vorbereitete Frage zu diesem Bild zurück. Wenn ich es richtig verstanden habe, ist Ihre Position, dass Lua ein kleines, nützliches Werkzeug ist, um nicht sehr große Aufgaben zu lösen.

- Nein, ich denke, Sie können einige große Aufgaben erledigen, aber nicht mit statischer Analyse. Ich glaube fest an Tests. Übrigens, ich bin mit Ihnen in Bezug auf die Berichterstattung nicht einverstanden. Ihre Meinung ist, wir sollten die Berichterstattung nicht verfolgen ... Ich meine, ich stimme voll und ganz zu, dass die Berichterstattung keinen vollständigen Test impliziert, aber die Nicht-Berichterstattung einen Null-Prozent-Test impliziert. Also hielt ich einen Vortrag über einen Testraum - Sie waren dort in Stockholm. Also habe ich meinen Test mit [ein paar] Fehlern begonnen - das ist das Seltsamste - einer von ihnen war berühmt, der andere war völlig nicht berühmt. In einer Header-Datei von Microsoft, C und C ++ ist etwas völlig kaputt. Also suche ich im Internet und niemand kümmert sich darum oder hat es überhaupt bemerkt.

Zum Beispiel gibt es eine mathematische Funktion, modf () , bei der Sie einen Zeiger auf ein Double übergeben müssen, da zwei Doubles zurückgegeben werden. Wir übersetzen den ganzzahligen Teil der Zahl oder den Bruchteil. Das ist also schon lange Teil einer Standardbibliothek. Dann kam C 99, und Sie benötigen diese Funktion für Floats. Und die Header-Datei von Microsoft hat diese Funktion einfach beibehalten und eine andere als Makro deklariert. Also hat es diesen in Typabgüsse gebracht. Also hat es das Double in Float umgewandelt, ok, und dann hat es den Zeiger in Double umgewandelt, damit der Zeiger schwebt!

- Auf diesem Bild stimmt etwas nicht.

- Dies ist eine Header-Datei aus Visual C ++ und Visual C 2007. Ich meine, wenn Sie diese Funktion einmal mit beliebigen Parametern aufgerufen und die Ergebnisse überprüft haben, wäre dies falsch, es sei denn, es ist Null. Andernfalls ist jeder andere Wert falsch. Sie würden diese Funktion niemals verwenden. Keine Abdeckung. Und dann gibt es viele Diskussionen über das Testen ... Ich meine, rufen Sie einfach einmal eine Funktion auf und überprüfen Sie die Ergebnisse! Also ist es da, es ist schon lange da, seit vielen Jahren kümmert es niemanden. Eine sehr berühmte war in Apple. So etwas wie " if… what… goto… ok " war es so etwas. Jemand hat hier eine andere Aussage gemacht. Und dann würde alles gut werden. Und es gab viele Diskussionen darüber, dass Sie die Regeln haben sollten, die Klammern in Ihrem Stil obligatorisch sein sollten usw. usw. Niemand hat erwähnt, dass es hier viele andere Wenns gibt. Das wurde noch nie ausgeführt ...

- Soweit ich mich erinnere, gibt es auch ein Sicherheitsproblem.

- Ja genau. Weil sie nur genehmigte Fälle testeten. Sie testeten nichts, weil alles genehmigt werden würde. Dies bedeutet, dass es in der Sicherheitsanwendung keinen einzigen Testfall gibt, der prüft, ob eine Verbindung abgelehnt wird oder was auch immer abgelehnt werden soll. Also diskutieren alle und sagen, sie sollten Klammern haben ... Sie sollten Tests haben, minimale Tests! Weil das noch niemand getestet hat, meine ich das mit Berichterstattung. Es ist unglaublich, wie Leute keine grundlegenden Tests machen. Denn wenn sie alle grundlegenden Tests durchführen würden, wäre es natürlich ein Albtraum, die gesamte Abdeckung durchzuführen und alle Zeilen usw. auszuführen. Die Leute vernachlässigen selbst grundlegende Tests, so dass die Abdeckung mindestens das Minimum ist. Auf diese Weise können Sie auf einige Teile des Programms aufmerksam machen, die Sie vergessen haben. Es ist eine Art Leitfaden, wie Sie Ihre Tests ein wenig verbessern können.

- Was ist Testabdeckung in Tarantool? 83%! Roberto, was ist Lua Testabdeckung?

- Über 99,6. Wie viele Codezeilen haben Sie? Eine Million, Hunderttausende? Das sind riesige Zahlen. Ein Prozent von hunderttausend sind tausend Codezeilen, die nie getestet wurden. Sie haben es überhaupt nicht ausgeführt. Ihre Benutzer testen nichts.

- Es gibt also etwa 17 Prozent der Tarantool-Funktionen, die derzeit nicht verwendet werden?

- Ich bin mir nicht sicher, ob Sie alles wieder dorthin bringen möchten, wo wir waren ... Ich denke, eines der Probleme mit dynamischen Sprachen (und statischen Sprachen) ist, dass die Leute keine Sachen testen. Selbst wenn Sie eine statische Sprache haben, ändern Sie das für das oder das, es sei denn, Sie haben etwas - nicht einmal wie Haskell, sondern Coq - ein Beweissystem. Kein statisches Analysetool kann diese Fehler erkennen, daher benötigen Sie Tests. Und wenn Sie die Tests haben, erkennen Sie globale Probleme, benennen Rechtschreibfehler um usw. All diese Arten von Fehlern. Sie sollten diese Tests sowieso haben, vielleicht ist es manchmal etwas schwieriger zu debuggen, manchmal nicht - hängt von der Sprache und der Art des Fehlers ab. Das Problem ist jedoch, dass Sie mit keinem statischen Analysetool Tests vermeiden können. Die Tests andererseits ... nun, sie beweisen nie die Abwesenheit von Fehlern, aber ich fühle mich nach all den Tests viel sicherer.

- Wir haben eine Frage zum Testen von Lua-Modulen. Als Entwickler möchte ich einige lokale Funktionen testen, die später verwendet werden können. Die Frage ist: Wir möchten eine Abdeckung von ungefähr 99 Prozent haben, aber für die API, die dieses Modul erzeugt, ist die Anzahl der Funktionsfälle, die es erzeugen sollte, viel geringer als die Funktionalität, die es intern unterstützt.

- Warum ist das so, sorry?

- Es gibt einige Funktionen, die über die öffentliche Schnittstelle nicht erreichbar sind.

- Wenn es Funktionen gibt, die über die öffentliche Schnittstelle nicht erreichbar sind, sollten sie nicht vorhanden sein. Löschen Sie sie einfach. Löschen Sie diesen Code.

- Töte es einfach?

- Ja, manchmal mache ich das in Lua. Es gab eine gewisse Codeabdeckung, ich konnte nicht dorthin oder dorthin oder dorthin gelangen, also hielt ich es für unmöglich und entfernte einfach den Code. Es ist nicht so üblich, aber es ist mehr als einmal passiert. Diese Fälle waren unmöglich zu passieren, Sie haben nur eine Aussage gemacht, um zu kommentieren, warum es nicht passieren kann. Wenn Sie nicht über die öffentliche API in Ihre Funktionen gelangen können, sollte diese nicht vorhanden sein. Wir sollten die öffentliche API mit falschen Eingaben codieren, was für die Tests wesentlich ist.

- Code entfernen, Entfernen ist gut, es reduziert die Komplexität. Eine reduzierte Komplexität erhöht die Wartbarkeit und Stabilität. Halte es einfach.

- Ja, extreme Programmierung hatte diese Regel. Wenn es sich nicht um einen Test handelt, existiert es nicht.

- Welche Sprachen haben dich inspiriert, als du Lua erschaffen hast? Welche Paradigmen oder funktionalen Besonderheiten oder Teile dieser Sprachen haben Ihnen gefallen?

- Ich habe Lua für einen ganz bestimmten Zweck entworfen, es war kein akademisches Projekt. Deshalb sage ich, wenn Sie mich fragen, ob ich es noch einmal erstellen würde, dass die Sprache viele historische Dinge enthält. Ich habe nicht mit "Lassen Sie mich die Sprache erstellen, die ich möchte oder verwenden möchte oder die jeder braucht usw." erstellt. Mein Problem war: 'Dieses Programm hier benötigt eine Konfigurationssprache für Geologen und Ingenieure, und ich muss eine kleine Sprache erstellen, die sie mit einer einfachen Oberfläche verwenden können. Deshalb war die API immer ein wesentlicher Bestandteil der Sprache, da sie einfacher zu integrieren ist. Das war das Ziel. Was ich in meinem Hintergrund hatte, es waren zu dieser Zeit viele verschiedene Sprachen ... ungefähr zehn. Wenn Sie den gesamten Hintergrund wollen ...

- Ich interessierte mich für Sprachen, die Sie in Lua aufnehmen wollten.

- Ich bekam Dinge aus vielen verschiedenen Sprachen, was auch immer zu meinem Problem passte. Die größte Inspiration war die Modula-Sprache für die Syntax, aber ansonsten ist es schwierig zu sagen, weil es so viele Sprachen gibt. Einige Sachen kamen von AWK, es war eine weitere kleine Inspiration. Natürlich, Scheme und Lisp ... Ich war immer fasziniert von Lisp, seit ich mit dem Programmieren angefangen habe.

- Und immer noch keine Makros in Lua!

- Ja, es gibt große Unterschiede in der Syntax. Ich glaube, Fortran war die erste Sprache ... nein, die erste Sprache, die ich lernte, war Versammlung, dann kam Fortran. Ich habe studiert, aber nie CLU verwendet. Ich habe viel mit Smalltalk, SNOBOL programmiert. Ich habe auch studiert, aber nie Icon verwendet, es ist auch sehr interessant. Vieles kam von Pascal und C. Als ich Lua erstellte, war C ++ für mich bereits zu komplex - und das war vor den Vorlagen usw. Es war 1991 und 1993 wurde Lua gegründet.

- Die Sowjetunion ist gefallen und du hast angefangen, Lua zu erschaffen. :) Warst du gelangweilt von Semikolons und Objekten, als du angefangen hast an Lua zu arbeiten? Ich würde erwarten, dass Lua eine ähnliche Syntax wie C hat, da sie in C integriert ist. Aber ...

- Ja, ich denke, es ist ein guter Grund, keine ähnliche Syntax zu haben - also mischen Sie sie nicht, das sind zwei verschiedene Sprachen.

Es ist etwas wirklich Lustiges und hängt mit der Antwort zusammen, die Sie mir [auf der Konferenz] nicht erlaubt haben, Arrays ab 1 zu geben. Meine Antwort war zu lang.

Als wir Lua starteten, war die Welt anders, nicht alles war C-ähnlich. Java und JavaScript gab es nicht, Python steckte noch in den Kinderschuhen und hatte eine Version unter 1.0. Es gab also nicht dieses Ding, wenn alle Sprachen C-ähnlich sein sollen. C war nur eine von vielen Syntaxen.

Und die Arrays waren genau die gleichen. Es ist sehr lustig, dass die meisten Leute das nicht merken. Es gibt gute Dinge über nullbasierte Arrays sowie über einsbasierte Arrays.

Tatsache ist, dass die meisten populären Sprachen heutzutage aufgrund von C auf Null basieren. Sie wurden irgendwie von C inspiriert. Und das Lustige ist, dass C keine Indizierung hat. Sie können also nicht sagen, dass C Arrays von Null indiziert, da es keine Indizierungsoperation gibt. C hat eine Zeigerarithmetik, daher ist Null in C kein Index, sondern ein Offset. Und als Offset muss es eine Null sein - nicht weil es bessere mathematische Eigenschaften hat oder weil es natürlicher ist, was auch immer.

Und all diese Sprachen, die C kopiert haben, haben Indizes und keine Zeigerarithmetik. Java, JavaScript usw. usw. - Keiner von ihnen hat Zeigerarithmetik. Sie haben also nur die Null kopiert, aber es ist eine ganz andere Operation. Sie setzen ohne Grund Null - es ist wie ein Frachtkult.

- Sie sagen, es ist logisch, wenn Sie eine Sprache in C eingebettet haben, um sie mit C-ähnlicher Syntax zu erstellen. Wenn Sie jedoch eine in C eingebettete Sprache haben, haben Sie vermutlich C-Programmierer, die möchten, dass der Code in C und nicht in einer anderen Sprache vorliegt, die wie C aussieht, aber nicht C ist. Daher sollten Lua-Benutzer niemals C verwenden täglich? Warum?

- Wer benutzt C jeden Tag?

- Systemprogrammierer.

- Genau. Das ist das Problem, zu viele Leute benutzen C, sollten es aber nicht benutzen dürfen. Programmierer sollten für die Verwendung von C zertifiziert sein. Warum ist Software so kaputt? All diese Hacks, die in die Welt eindringen, all diese Sicherheitsprobleme. Mindestens die Hälfte von ihnen ist wegen C. Es ist wirklich schwer, in C zu programmieren.

- Aber Lua ist in C.

- Ja, und so haben wir gelernt, wie schwierig es ist, in C zu programmieren. Sie haben Pufferüberläufe, Sie haben ganzzahlige Überläufe, die Pufferüberläufe verursachen ... Holen Sie sich einfach ein einzelnes C-Programm, bei dem Sie sicher sein können, dass keine Arithmetik schief geht, wenn Leute es setzen Beliebige Nummer überall und alles wird überprüft. Andererseits echte Portabilitätsprobleme - vielleicht funktioniert es manchmal in einer CPU, aber dann gelangt es zur anderen CPU ... Es ist verrückt.

Zum Beispiel hatten wir kürzlich ein Problem. Woher wissen Sie, dass Ihr C-Programm keinen Stapelüberlauf ausführt? Ich meine Stapeltiefe, nicht Stapelüberlauf, weil Sie eingedrungen sind ... Wie viele Aufrufe haben Sie in einem C-Programm?

- Abhängig von der Stapelgröße.

- Genau. Was sagt der Standard dazu? Wenn Sie in C codieren und dann diese Funktion ausführen, die diese Funktion aufruft, die diese Funktion aufruft ... wie viele Aufrufe können Sie ausführen?

- 16 Tausend?

- Ich kann mich irren, aber ich denke, der Standard sagt nichts darüber aus.

- Ich denke, der Standard enthält nichts, weil er zu stark von der Größe abhängt.

- Natürlich hängt es von der Größe jeder Funktion ab. Es können riesige, automatische Arrays im Funktionsrahmen sein ... Der Standard sagt also nichts und es gibt keine Möglichkeit zu überprüfen, ob ein Aufruf gültig ist. Wenn Sie also drei Schrittaufrufe haben, kann dies zu einem einzigen Problem führen. Es kann abstürzen und dennoch ein gültiges C-Programm sein. Korrigieren Sie gemäß dem Standard - obwohl es nicht korrekt ist, weil es abstürzt. Es ist also sehr schwer, in C zu programmieren, weil es so viele gibt ... Ein weiteres gutes Beispiel: Was ist das Ergebnis, wenn Sie zwei Zeiger subtrahieren? Niemand hier arbeitet mit C?

- Nein, also grillen Sie sie nicht. C ++ unterstützt jedoch verschiedene Typen.

- Nein, C ++ hat das gleiche Problem.

- Was ist die Art der Erklärung? ptrdiff_t ?

- Genau, ptrdiff_t ist ein signierter Typ. Wenn Sie also einen Standardspeicher mit der Größe Ihres Wortes haben und zwei Zeiger in diesem Bereich subtrahieren, können Sie normalerweise nicht alle Größen im signierten Typ darstellen. Was sagt der Standard dazu?

Wenn Sie zwei Zeiger subtrahieren und die Antwort in einen Zeigerdifferenz passt, ist dies die Antwort. Ansonsten haben Sie undefiniertes Verhalten. Und woher weißt du, ob es passt? Das tust du nicht. Wenn Sie also zwei Zeiger subtrahieren, wissen Sie normalerweise, dass dies nicht dem Standard entspricht. Wenn Sie auf etwas zeigen, das größer als mindestens 2 Byte ist, ist die größere Größe halb so groß wie der Speicher, sodass alles in Ordnung ist.

Sie haben also nur dann ein Problem, wenn Sie auf Bytes oder Zeichen zeigen. Aber wenn Sie das tun, haben Sie ein echtes Problem. Sie können keine Zeigerarithmetik durchführen, ohne sich Sorgen machen zu müssen, dass Sie eine Zeichenfolge haben, die größer als die Hälfte des Speichers ist. Und dann kann ich nicht einfach die Größe berechnen und in einem Zeigerdiff-Typ speichern, weil es falsch ist.

Das meine ich mit einem sicheren C- oder C ++ - Programm, das wirklich sicher ist.

- Haben Sie darüber nachgedacht, Lua in einer anderen Sprache zu implementieren? Ändern Sie es von C zu etwas anderem?

- Als wir angefangen haben, habe ich über C ++ nachgedacht, aber wie gesagt, ich habe es wegen der Komplexität aufgegeben - ich kann nicht die ganze Sprache lernen. Es sollte nützlich sein, ein paar Sachen aus C ++ zu haben, aber ... bis heute sehe ich keine Sprache, die das tun würde.

- Kannst du erklären warum?

- Weil ich keine Alternativen habe. Ich kann nur erklären, warum gegen andere Sprachen. Ich sage nicht, dass C perfekt oder sogar gut ist, aber es ist das Beste. Um zu erklären warum, muss ich es mit anderen Sprachen vergleichen.

- Was ist mit JVM?

- Oh, JVM. Komm schon, es passt nicht in die Hälfte der Hardware ... Portabilität ist der Hauptgrund, aber auch Leistung. In JVM ist es ein bisschen besser als .NET, aber es ist nicht so anders. Viele Dinge, die Lua tut, können wir mit JVM nicht tun. Sie können beispielsweise den Garbage Collector nicht steuern. Sie müssen den JVM-Garbage Collector verwenden, da auf JVM kein anderer Garbage Collector implementiert werden kann. JVM ist auch ein großer Speicherkonsument. Wenn ein Java-Programm anfängt, Hallo zu sagen, sind es ungefähr 10 MB. Portabilität ist ein Problem, nicht weil es nicht portiert wurde, sondern weil es nicht portiert werden kann.

- Was ist mit JVM-Modifikationen wie Mobile JVM?

- Das ist keine JVM, das ist ein Witz. Es ist wie eine Micro Edition von Java, nicht Java.

- Wie wäre es mit anderen statischen Sprachen wie Go oder Oberon? Könnten sie die Basis für Lua sein, wenn Sie es heute schaffen würden?

- Oberon ... könnte sein, es kommt darauf an ... Go hat wieder einen Müllsammler und eine zu große Laufzeit für Lua. Oberon wäre eine Option, aber Oberon hat einige sehr seltsame Dinge, wie Sie fast keine Konstanten haben, wenn ich mich richtig erinnere. Ja, ich denke, sie haben const von Pascal nach Oberon entfernt. Ich hatte ein Buch über Oberon und liebte Oberon. Das System war unglaublich, es ist wirklich etwas.

Ich erinnere mich, dass ich 1994 eine Demonstration von Oberon und Self gesehen habe. Kennst du dich selbst? Es ist eine sehr interessante dynamische Sprache mit Jit-Compilern usw. Ich habe diese Demos im Abstand von einer Woche gesehen, und Self war sehr schlau. Sie verwendeten einige Techniken aus Cartoons, um die Langsamkeit der Operationen zu verschleiern. Denn als du etwas geöffnet hast, war es wie 'woop!' - zuerst reduziert es sich ein wenig, dann dehnt es sich mit einigen Effekten aus. Es wurde sehr gut implementiert, diese Techniken verwendeten sie, um Bewegung zu simulieren ...

Dann, eine Woche später, sahen wir eine Demo von Oberon, die auf 1/10 der Hardware für Self lief - da war diese sehr alte kleine Maschine. In Oberon klickt man und boomt dann einfach, alles funktioniert sofort, das ganze System war so leicht.

Aber für mich ist es zu minimalistisch, sie haben Konstanten und Variantentypen entfernt.

- Haskell?

- Ich weiß nicht, wie Haskell Lua in Haskell implementiert.

- Und wie stehen Sie zu Sprachen wie Python oder R oder Julia als Grundlage für zukünftige Implementierungen von Lua?

- Ich denke, jeder von diesen hat seinen Nutzen.

R scheint gut für Statistiken zu sein. Es ist sehr domänenspezifisch und wird von Menschen in der Region durchgeführt. Dies ist also eine Stärke.

Python ist nett, aber ich hatte persönliche Probleme damit. Ich dachte, ich hätte es in meinem Vortrag oder im Interview erwähnt. Das Ding, die ganze Sprache nicht zu kennen oder sie nicht zu benutzen, der Irrtum der Teilmenge.

Wir verwenden Python in unseren Kursen und unterrichten grundlegende Programmierung - nur einen kleinen Teil, Schleifen und ganze Zahlen. Alle waren glücklich und sagten dann, es wäre schön, einige grafische Anwendungen zu haben, also brauchten wir eine grafische Bibliothek. Und bei fast allen grafischen Bibliotheken erhalten Sie die API ... Aber ich kenne Python nicht genug, das ist viel fortgeschrittenes Zeug. Es hat die Illusion, dass es einfach ist und ich habe all diese Bibliotheken für alles, aber es ist entweder einfach oder Sie haben alles.

Wenn Sie also anfangen, die Sprache zu verwenden, dann fangen Sie an: Oh, ich muss OOP lernen, Vererbung, was auch immer. Jede einzelne Bibliothek. Es sieht so aus, als ob Autoren stolz darauf sind, erweiterte Sprachfunktionen in ihrer API zu verwenden, um zu zeigen, dass ich nicht weiß, was. Funktionsaufrufe, Standardtypen usw. Sie haben dieses Objekt und wenn Sie etwas anderes wollen, müssen Sie ein anderes Objekt erstellen ...

Selbst beim Mustervergleich können Sie einige einfache Dinge tun, aber normalerweise ist der Standardmustervergleich nicht etwas, was Sie tun. Sie führen einen Abgleich durch, ein Objekt gibt ein Ergebnis zurück und rufen dann Methoden für dieses Objektergebnis auf, um das tatsächliche Ergebnis des Abgleichs zu erhalten. Manchmal gibt es einen einfacheren Weg, aber es ist nicht offensichtlich, es ist nicht der Weg, den die meisten Leute benutzen.

Ein weiteres Beispiel: Ich unterrichtete einen Kurs zum Pattern Matching und wollte Perl-ähnliche Syntax verwenden. Aufgrund einer völlig anderen Syntax konnte ich Lua nicht verwenden. Also dachte ich, Python wäre das perfekte Beispiel. Aber in Python gibt es einige direkte Funktionen für einige grundlegende Dinge, aber für alles Komplexere müsste man Objekte und Methoden usw. kennen. Ich wollte nur etwas tun und das Ergebnis haben.

- Was hast du letztendlich benutzt?

- Ich habe Python benutzt und es ihnen erklärt. Aber selbst Perl ist viel einfacher, Sie machen das Match und die Ergebnisse sind $ 1, $ 2, $ 3, es ist viel einfacher, aber ich habe nicht den Mut, Perl zu verwenden, also ...

- Ich habe Python zwei Jahre lang verwendet, bevor ich bemerkte, dass es Dekorateure gab. (Frage von Jaroslaw Dynnikow vom Tarantool-Team)

- Ja, und wenn Sie eine Bibliothek verwenden möchten, müssen Sie dieses Zeug lernen und verstehen API usw. nicht. Python gibt die Illusion, dass es einfach, aber ziemlich komplex ist.

... Und Julia, ich weiß nicht viel über Julia, aber es erinnerte mich an LuaJIT in dem Sinne, dass es manchmal wie der Stolz des Benutzers aussieht. Sie können sehr gute Ergebnisse erzielen, aber Sie müssen wirklich verstehen, was los ist. Es ist nicht so, dass Sie Code schreiben und gute Ergebnisse erzielen. Nein, Sie schreiben Code und manchmal sind die Ergebnisse gut, manchmal sind sie schrecklich. Und wenn die Ergebnisse schrecklich sind, haben Sie viele gute Tools, die Ihnen die Zwischensprache zeigen, die einmal generiert wurde. Sie überprüfen sie und gehen dann den gesamten fast Assembler-Code durch. Dann merkt man: Oh, das wird deshalb nicht optimiert. Das ist das Problem der Programmierer, sie mögen Spiele und manchmal mögen sie Dinge, weil es schwierig ist, nicht weil es einfach ist.

Ich weiß nicht viel über Julia, aber ich habe einmal ein Gespräch darüber gesehen. Und der Typ, der redet, war derjenige, der diesen Standpunkt vertrat: Sehen Sie, wie schön es ist, wir haben dieses Programm geschrieben und es ist perfekt. Ich erinnere mich nicht viel an etwas über Matrixmultiplikation, denke ich. Und dann sind die Wagen perfekt, dann sind die Doppel perfekt, und dann setzen sie komplexe [Zahlen] ... und es war eine Tragödie. Wie hundertmal langsamer.

(sarkastisch) 'Sehen Sie, wie schön es ist, wir haben dieses Werkzeug, wir können die gesamte Baugruppe [Auflistung] sehen, und dann gehen Sie und ändern das und das und das. Sehen Sie, wie effizient dies ist. Ja, ich verstehe, ich kann direkt in der Montage programmieren.

Aber das war nur ein Gespräch. Ich habe ein wenig R studiert und habe einige Benutzererfahrungen mit Python für kleine Dinge.

- Was denkst du über Erlang?

- Erlang ist eine lustige Sprache. Es hat einige wirklich gute Anwendungen, Fehlertoleranz ist wirklich interessant. Aber sie behaupten, es sei eine funktionale Sprache und die ganze Idee der funktionalen Sprache ist, dass Sie keinen Zustand haben.

Und Erlang hat einen riesigen versteckten Zustand in den Nachrichten, die gesendet und noch nicht empfangen werden. Jeder kleine Prozess ist also voll funktionsfähig, aber das Programm selbst ist völlig funktionsunfähig.

Es ist ein Durcheinander von versteckten Daten, das viel schlimmer ist als globale Variablen, denn wenn es globale Variablen wären, würden Sie sie drucken. Nachrichten, die den tatsächlichen Status Ihres Systems darstellen. Wie ist der Zustand des Systems in jedem einzelnen Moment? Es werden all diese Nachrichten hier und da gesendet. Es ist überhaupt nicht funktionsfähig.

- Erlang lügt also, funktional zu sein, und Python lügt, einfach zu sein. Worüber lügt Lua?

- Lua lügt ein bisschen darüber, klein zu sein. Es ist immer noch kleiner als die meisten anderen Sprachen, aber wenn Sie eine wirklich kleine Sprache wollen, ist Lua größer als Sie wollen.

- Was ist dann eine kleine Sprache?

- Forth ist, ich liebe Forth.

- Gibt es Platz für eine kleinere Version von Lua?

- Vielleicht, aber es ist schwierig. Ich liebe Tische, aber Tische sind nicht sehr klein. Wenn Sie kleine Dinge darstellen möchten, passt die ganze Idee hinter Tischen nicht zu Ihnen. Es wäre die Syntax von Lua, wir würden es Lua nennen, aber es ist nicht Lua.

Es wäre genau wie bei der Java Micro Edition. Sie nennen es Java, aber hat es Multithreading? Nein, das tut es nicht. Hat es ein Spiegelbild? Nein, das tut es nicht. Warum also? Es hat eine Java-Syntax, das gleiche System, aber es ist überhaupt kein Java. Es ist eine andere Sprache, die leichter zu lernen ist, wenn Sie Java kennen, aber nicht Java.

Wenn Sie eine kleine Sprache erstellen möchten, die wie Lua aussieht, Lua ohne Tabellen jedoch nicht ... Wahrscheinlich sollten Sie Tabellen deklarieren müssen, so etwas wie FFI, um klein sein zu können.

- Gibt es kleinere Anpassungen von Lua?

- Vielleicht weiß ich es nicht.

- Ist Lua bereit für eine reine funktionale Programmierung? Schaffst du das mit Lua?

- Natürlich kannst du. Es ist nicht besonders effizient, aber nur Haskell ist dafür wirklich effizient. Wenn Sie anfangen, Monaden und ähnliches zu verwenden, neue Funktionen erstellen, Funktionen komponieren usw. Sie können [das] mit Lua tun, es läuft ziemlich vernünftig, aber Sie benötigen Implementierungstechniken, die sich von normalen imperativen Sprachen unterscheiden, um etwas wirklich Effizientes zu tun.

— 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!

Source: https://habr.com/ru/post/de459466/


All Articles