Ich habe mal wieder ein neues Hobbyprojekt.
Nachdem Objective-CL sich ja nunmehr sehen lassen und prinzipiell produktiv verwendet werden kann, habe ich mich an den nächsten Schritt gewagt: ein Lispcompiler für Étoilé bzw. GNUstep und Mac OS X, der vollständig auf der Objective-C-Runtime aufbaut und sich mit ihr integriert. Derzeitiger Projektname: Toilet Lisp.
Nun, um ehrlich zu sein, habe ich keine Ahnung von Übersetzerbau (welcher sicherlich nicht einfach ist), weshalb Toilet Lisp in der ersten Phase nur einen Interpreter enthalten wird und keinen Compiler. Ein Zwischenschritt könnte ein Compiler nach Objective-C-Code sein, der via clang oder GCC weiterkompiliert wird, und das Endziel ist ein Compiler, der LLVM-Code erzeugt.
So oder so werde ich für Toilet Lisp wahrscheinlich länger brauchen als für Objective-CL, bis ich etwas in der Praxis Nützliches produziert habe. Ob überhaupt etwas daraus wird, steht in den Sternen. Aber es ist sicher ganz lehrreich. Auch, wenn sonst niemand etwas davon haben sollte, versuche ich es deshalb trotzdem.
Vielleicht sollte ich noch eine Frage beantworten, die sich unmittelbar aufdrängt: Warum schon wieder ein neuer Lispcompiler, wenn es schon so viele gibt? Vor allem: Gibt es nicht schon Lisps auf der Objective-C-Runtime?
Die gibt es in der Tat. Sie sind aber allesamt semantische Neuerfindungen. Ich halte mich hingegen soweit wie nur irgend möglich an ANSI Common Lisp. Die Kombination einer vollständig mit Objective-C integrierten Umgebung einerseits und traditionellem Lisp andererseits existiert in dieser Form noch nicht. (Pragmatisch betrachtet, kommt Clozure CL mit der gut integrierten Objective-C-Bridge zwar an die Idee einigermaßen nahe heran, aber leider ist es sehr unportabel. Eines von Toilet Lisps Zielen ist es, unter allen Betriebssystemen mit einer Objective-C-Runtime zu laufen und kompakte, klickbare Binaries zu erzeugen.)
Die großen Ziele zusammengefaßt:
Portabilität. Zur Not muß man je nach Plattform eben ohne Compiler auskommen, aber laufen soll das System überall.
Codelesbarkeit. Im Zweifel auch zu Lasten der Performance.
Integration mit Objective-C und Ausnutzung der Runtimefunktionen statt Neuerfindung (z.B. die Implementierung von
CATCH
undTHROW
über das bestehende Exception-System).Kompatibilität mit bestehendem ANSI-CL-Code, insbesondere Bibliotheken.
- Unterstützung sowohl eines lispigen, interaktiven als auch eines unixfreundlichen uninteraktiven Entwicklungsmodus, d.h. z.B. Erzeugung von Bibliotheken und Programmen mit Dingen wie
make
statt aus dem laufenden Lispsystem heraus. Insbesondere: keine Kernbilder (solche wären auf der Objective-C-Runtime auch gar nicht portabel zu realisieren).
Comments
Sind alles wichtige Punkte, die oft vernachlässigt werden. Leider. Aber, lassen sich Kernbilder nicht auch so erzeugen, dass man sie in Form von ObjectiveC-Quellcode (der Portabel ist) abspeichern kann, den man Compilieren kann? Sicher nicht trivial, und etwas unhandlich, wenn man seinen Coredump dann compilieren muss (man kann das ja als Option offenlassen), aber nichts unmögliches.
Kernbilder als Objective-C-Quell- bzw. Objektcode abzuspeichern, dürfte sich als ziemlich nichttrivial bis praktisch unmöglich erweisen. Da Kernbilder den gesamten Systemzustand sichern müssen, müßte man jedes Objekt im System serialisieren; aber das geht im allgemeinen in Objective-C nicht, weil es ein Mischmasch aus C und Smalltalk ist. Der Smalltalkteil wäre leicht zu behandeln; einzig der C-Teil macht einem einen Strich durch die Rechnung: Wie rekonstruiert man einen Systemzustand, wenn man Zeiger nicht von Zahlen unterscheiden kann? Richtig: indem man jedes Objekt und jeden mit malloc(2) reservierten Speicherbereich exakt an derselben Stelle wiederherstellt, an der sie vor dem Sichern waren. Dafür muß man in der Tat ein echtes Kernbild erstellen, also ein Speicherabbild des Systems. Anders ist es, denke ich, nicht zu realisieren.
Lisp bietet im übrigen bereits eine Möglichkeit, so etwas ähnliches wie Kernbilder in Quell- bzw. Objektform zu speichern: FASLs. Man kann durchaus sehr komplexe Gebilde in einer FASL-Datei ablegen, nicht nur direkt aus einem Quelltext kompilierten Code (siehe dazu den CLHS-Eintrag zu MAKE-LOAD-FORM). Tatsächlich kann ja in einem Stück Code jedes beliebige Objekt eingebettet sein, etwas, das in anderen Programmiersprachen undenkbar und auch in Lisp auf den ersten Blick gar nicht offensichtlich ist. Das ist die vielbeschworene Äquivalenz von Code und Daten: In Common Lisp sind sie nicht nur äquivalent bis auf Isomorphie (wie z.B. in Scheme), sondern vollkommen identisch.
Nota bene: (compile nil `(lambda () ,(make-hash-table))) ist wohldefiniert! Ich habe lange gebraucht, um das wirklich zu begreifen.
Submit a comment
Note: This website uses a JavaScript-based spam prevention system. Please enable JavaScript in your browser to post comments. Comment format is plain text. Use blank lines to separate paragraphs.