- Lone Lisp ist ein Lisp, das ohne
libcdirekt auf Linux-Systemaufrufen läuft. Matheus Moreira begann das Projekt, um herauszufinden, ob sich allein mit freestanding C eine vollständige Sprache und User-Space-Programme bauen lassen. - Durch die direkte Nutzung der stabilen Linux-User-Space-ABI entfernt es globalen Zustand und Legacy-APIs von C-Bibliotheken wie
errno, Locale und implizites Dateibuffering und implementiert Runtime, Speicherallokator und Testwerkzeuge selbst. - Es unterstützt FEXPR und Proper Tail Call Optimization sowie Generatoren, delimited continuations und wiederaufnehmbare Fehlerbehandlung; auch Vektoren, Tabellen und Continuations werden mit demselben Funktionsaufrufmodell behandelt.
- Der Start ist schnell, aber in vorläufigen Benchmarks ist es ein Interpreter auf Listenebene, der 10- bis 100-mal langsamer als Python ist; langfristig soll ein JIT-Compiler in Lone selbst entstehen, während der C-Interpreter als Bootstrap-Basis bleibt.
- Moreira nutzt Claude für Code-Review und Projektmanagement, schreibt und prüft den Lone-Code aber selbst und will mit statischem Site-Generator, Shell und Utilities den traditionellen Linux-User-Space neu aufbauen.
Von Spielen zu C++, Ruby und Lisp
- Sein Interesse am Programmieren begann mit Mega Man Battle Network; um sich in zugehörigen Foren auszutauschen, lernte er Englisch und auch seine erste Sprache C++.
- An einer technischen Oberschule in Brasilien begann er mit etwa 13 bis 14 Jahren eine Informatikausbildung.
- Er nutzte Dev-C++ und Tutorials auf cplusplus.com.
- Nach sechs Monaten hatte er den gesamten Schulstoff gelernt und wurde als Assistent eingestellt, um anderen Schülern zu helfen.
- Er versuchte sich auch an Spieleentwicklung, scheiterte aber am fehlenden Physikwissen.
- Nach C++ kam er über Java, Ruby und Python zu Lisp und Scheme und fühlte sich von der sprachlichen Eleganz von Scheme angezogen.
- Er las fast das komplette Java-Tutorial von Sun und lernte so objektorientierte Programmierung.
- Er mochte Java Swing und das Nimbus-Design und baute sogar eine App zum Zeichnen von Kreisen und Bögen für einen Mathematikprofessor.
- In Ruby schrieb er Gems, darunter den Git-artigen, befehlsbasierten Argument-Parser Acclaim.
- Der Antrieb, viele Sprachen zu erkunden, kam zunächst aus Schulprojekten, später aber vor allem aus Neugier und dem Wunsch, die richtige Sprache für sich zu finden.
Die Ausdruckskraft von Ruby und die Transparenz von C
- Bei Ruby traf er oft selbst mit erratenen Methodennamen ins Schwarze, und Unterstützung für Singular/Plural sowie Synonyme passte gut zu seiner Denkweise.
- Mit Kombinationen wie
items.each.with_index.map, die nah an Shell-Pipelines liegen, lässt sich mit wenig Code viel erledigen. - Er installiert Ruby bis heute immer mit und hat kürzlich wieder ein Rails-Projekt begonnen.
- Mit Kombinationen wie
- Bei C gefiel ihm, dass Funktionen direkt ELF-Symbolen und Assemblercode entsprechen und sich das Kompilierungsergebnis dadurch leicht verstehen lässt.
- Modernes C++ sei praktisch eine andere Sprache als früher, weshalb er nicht mehr behauptet, C++ zu beherrschen.
- Er versuchte zu Rust zu wechseln, blieb aber nicht dabei, und interessiert sich auch für Zig und dessen Gründer, die Gründe für Umschreibungen in C in Geschwindigkeit und ABI sehen.
- Schon als Teenager las er den Quellcode der CRuby-VM und suchte auf Stack Overflow bei Fragen wie „Warum verhält sich Ruby so?“ die Antwort in der Implementierung.
- Später durchforstete er Code von CRuby, CPython, der JVM, Guile und V8 und sieht besonders den Linux-Kernel-Quellcode als Maßstab für professionelles C-Programmieren.
Wie er fremden Code liest
- Er beschränkt sich nicht aufs Nutzen von Bibliotheken, sondern liest fortlaufend Quellcode, um interne Implementierungen, die Kommunikation zwischen Treibern und Hardware und verborgene Schichten zu verstehen.
- Selbst wenn er reale Anwendungen baute, glitt er oft in die Erforschung der zugrunde liegenden Technik ab und entwickelte die Neigung, bereits gelöste Probleme besser noch einmal zu bauen.
- Weil diese Neigung seiner Ansicht nach nicht gut zu einer üblichen Karriere in der Softwareentwicklung passt, entschied er sich, Programmierung nicht zum Beruf zu machen, sondern als Hobby zu behalten.
- Treibercode verstand er anfangs natürlich nicht; trotz Frustration las er weiter, bis er Teile des Verhaltens nachvollziehen konnte.
Reverse Engineering einer RGB-Tastatur
- Die Windows-App zur Steuerung der RGB-Tastatur seines Clevo-Barebone-Laptops war so langsam, dass allein das Öffnen des Fensters über eine Minute dauerte, also ersetzte er sie selbst.
- Mit Wireshark zeichnete er USB-Pakete auf, die die App an die Tastatur sendete, analysierte deren Struktur und schrieb einen Linux-User-Space-Treiber in C.
- Nach dem Upload auf GitHub vergaß er das Projekt, doch es fand echte Nutzer, und einer davon baute sogar ein GUI dazu.
- Danach betrieb er auch Reverse Engineering weiterer Notebook-Funktionen wie ACPI-Power-Management, konnte aber nicht alles entschlüsseln.
liblinux ohne libc
- Linux-Systemaufrufe sind im Code so einfach, dass sie fast gewöhnlichen Funktionsaufrufen gleichen, und man kann Linux direkt als Ziel ansprechen, ohne durch
libczu gehen. - Linux ist zwar für die Stabilität seiner User-Space-ABI bekannt, seine User-Space-Komponenten seien es seiner Ansicht nach aber nicht.
- In Handbuchseiten stieß er auf den Hinweis, dass glibc manche Systemaufrufe nicht unterstützt.
- Ebenfalls prägte ihn ein Fall bei LWN, in dem
getrandometwa zwei Jahre brauchte, bis es in glibc aufgenommen wurde.
- Aus der Idee, eine
liblinux.azu bauen und mit-llinuxzu linken, entstand liblinux.- Es war eine Sammlung von Linux-Systemaufruf-Wrappern für freestanding C.
- Mit C-Runtime (CRT) sind Standard-C-Bibliotheken wie glibc, musl oder uclibc gemeint.
Welche Probleme in freestanding C verschwinden
- Linux liefert Fehler als normale Rückgabewerte zurück, C-Bibliotheken speichern sie dagegen in der globalen Variablen
errno. - Wenn
libcwegfällt, lassen sich damit auch mehrere globale Zustände und alte APIs vermeiden.errno,rand/srand, Locale-Zustand- das nicht reentrante
strtok - implizites Dateibuffering, das unerwartete Probleme verursachen kann
gets,atexit,signal,mallocmath.h, das in Kombination mit NaN underrnokomplex wird
- Integer-Promotion-Regeln und fehlende Overflow-Prüfung sind dagegen Probleme von C selbst und bleiben bestehen.
- Für Overflows nutzt er Compiler-Built-ins.
- Er achtet zugleich darauf, nicht selbst neue Fehlerquellen zu schaffen.
- Ohne Standardbibliothek musste er alles von Byte-Kopien bis zur Umwandlung von Integern in Strings selbst schreiben, doch es war nicht so unmöglich, wie erwartet.
- Das glibc-Repository war schwer zu lesen, aber der Quellcode von
musl libcwar sauber und leicht zu durchstöbern und half enorm. - Auch eine automatische Testsuite, die ohne C-Bibliothek und dynamische Speicherallokation nur mit statischem Speicher arbeitet, implementierte er in Lone.
- Das glibc-Repository war schwer zu lesen, aber der Quellcode von
Entdeckung von nolibc und Beginn von Lone Lisp
- Er fragte Greg Kroah-Hartman, warum Linux keine offizielle C-Bibliothek habe, und erhielt die Antwort, dass es früher das Projekt klibc gegeben habe.
- Später entdeckte er, dass Linux-Kernel-Entwickler für interne Werkzeuge nolibc.h gebaut hatten.
- Er hielt es für ausgereifter und benutzbarer als sein eigenes liblinux und archivierte das Projekt daher.
- Heute ist
nolibc.hinnerhalb des Kernel-Baums zu einem Verzeichnis gewachsen, das fast einer provisorischenlibcähnelt, doch eine stabile externe Schnittstelle ist nicht sicher zugesagt.
- Als nächstes Projekt begann er Lone Lisp.
- Wenn sich ein freestanding Lisp bauen lässt, das direkt auf Linux läuft, dann müssten sich seiner Ansicht nach auch andere Programme so schreiben lassen.
- Es ist ein Experiment, den komplexen modernen Linux-User-Space abzutragen und auf der stabilen binären Schnittstelle der Systemaufrufe neu zu beginnen.
- Auch an Cosmopolitan schickte er Patches, etwa für die Implementierung von Fließkomma-Parsing.
- Besonders schätzt er das APE-Format, das gleichzeitig als ausführbares Dateiformat auf mehreren Plattformen interpretiert werden kann, und die Funktion für eingebettete Archive in Executables.
Fehlerbehandlung und delimited continuations
- In frühem Lone endeten alle Fehlerpfade im Interpreter mit
exit(255), später implementierte er jedoch ein wiederaufnehmbares Condition-System nach Common-Lisp-Art. - Grundlage der Fehlerbehandlung sind delimited continuations.
- Er versteht Continuations als das Kopieren von Stack-Frames und deren Wiedergabe an anderer Stelle.
- Auch Ausnahmen sieht er als eine Form von Continuation, die keinen Wert erfasst.
- Fehlerarten werden von Symbolen wie
'not-foundauf Lambdas abgebildet.- Ein
(lambda (error) ...)mit einem Argument verhält sich wie ein normaler Exception-Handler. - Ein
(lambda (error continuation) ...)mit zwei Argumenten kann die Continuation aufrufen und den Code, in dem der Fehler auftrat, mit einem Wert fortsetzen.
- Ein
- Eine Restart-API, bei der signalisierender Code wie in Common Lisp mit
use-valuemögliche Neustarts aufzählt, übernimmt er bewusst nicht.- Stattdessen baut er
signal,throwundtransferals Grundmechanismen in den Evaluator ein, sodass sie sich so verhalten, als würden sie einfach Werte zurückgeben.
- Stattdessen baut er
FEXPR und aufrufbare Sprachelemente
- Auch das traditionelle Lisp-Evaluator-Modell, bei dem Sonderformen wie
ifdirekt behandelt werden, wollte er vermeiden. - Lone unterstützt FEXPR als eine Art Evaluator-Plugin und verlagert Sonderformen damit aus dem Evaluator heraus.
- Mit diesem Design funktionierte Tail-Call-Optimierung für reine Lisp-Funktionen zuerst, bei Primitives gab es aber eine Zeit lang Bugs.
- Gelöst wurde das durch einen separaten Mechanismus, mit dem Primitives in Tail-Position zurückkehren können.
- Auch Vektoren und Tabellen sind aufrufbar.
([1 2 3] 0)gibt1zurück.([1 2 3] 0 4)verändert den Vektor zu[4 2 3].
- Continuations und Generatoren folgen derselben Aufrufkonvention.
controlähnelt einembegin, das Continuations unterstützt.transferverlässt den nächstgelegenencontrol-Block und gibt eine aufrufbare Continuation zurück, die den Unterbrechungspunkt repräsentiert.- Ruft man diese Continuation mit einem Wert auf, wird die unterbrochene Berechnung mit einem anderen Rückgabewert fortgesetzt.
Systemaufrufe und Ausführungsstruktur
- Vor dem Start von Lone ruft der Elternprozess
execveauf, und Lone selbst führt für seine interne Speicherverwaltung ungefähr 12mmap-Aufrufe aus. - Es liest ein Skript von der Standardeingabe, führt es aus und beendet sich; währenddessen können zusätzlich
mmap,munmapundmremapauftreten. - Das Modulsystem nutzt
openatundclose. - Von den über 300 Linux-Systemaufrufen verwendet es selbst nur einige, stellt auf Lisp-Ebene aber ein System-Call-Primitive bereit, über das Programme auch die übrigen aufrufen können.
- Für Aufrufe wie
ioctl, die Kernel-C-Strukturen benötigen, muss Unterstützung zum Erzeugen und Bearbeiten solcher Strukturen hinzukommen.- Auch das Abfragen der Terminalgröße ist ein Fall, der solche Unterstützung braucht.
Der User-Space, den er mit Lone bauen will
- Auf Sprachebene sind Fehlerbehandlung, Proper Tail Call Optimization, Generatoren und delimited continuations bereits implementiert, langfristig will er auch Ideen aus Erlang/BEAM einbringen.
- Die Struktur ist so vorbereitet, dass mehrere Interpreter Lisp-Code parallel ausführen können.
- Das erste Programm, das er mit Lone bauen will, ist ein Ersatz für den aktuell genutzten statischen Site-Generator auf Basis eines PugJS-Forks.
- Danach will er eine eigene Shell und Utilities schreiben, um den traditionellen Linux-User-Space auf seine Weise neu zu erschaffen.
- Er hat auch eine Implementierung gebaut, die
envals Lone-Lisp-Tabelle exportiert; damals fehlte noch Iteration, inzwischen gibt es Generatoren. - Der Interpreter kann außerdem Lisp-Code aus einem speziellen ELF-Segment lesen und ausführen.
- Kopiert man das Interpreter-Binary und fügt Lisp-Code ein, lässt sich ein eigenständig ausführbares Programm erzeugen.
Review und Projektmanagement mit Claude
- Er sieht keine Grenze für die Gesamtarbeitsmenge, glaubt aber, dass der Funktionsumfang der Sprache selbst allmählich nahe an der Vollendung ist.
- Claude nutzt er gewissermaßen als Manager und bekommt vor allem bei Code-Review und Projektmanagement großen Nutzen.
- Er bittet darum, im gesamten Codebestand streng nach Problemen, noch unentwickelten Bereichen und zukünftigen Richtungen zu suchen.
- Abgelehnte Ansätze und später zu erledigende Funktionen verwaltet er in Dokumenten und einer Projekt-Memory.
- Garbage Collector und Speicherallokator wurden deutlich besser, weil Claude ihm bessere Algorithmen zeigte.
- Jede Zeile, die in Lone einfließt, prüft er selbst, und weil er das Schreiben von Code an sich für lehrreich hält, vertraut er nicht darauf, dass KI den Lone-Code für ihn schreibt.
- Bei einem JavaScript-Site-Generator ließ er Claude dagegen schon einmal ganze Funktionen schreiben.
- Geplante Features sind unter anderem Unterstützung für GCC-/Clang-Compiler-APIs und Stack-Protection-Funktionen.
Syntax aus Ruby und Scheme
- Er wollte die Ausdruckskraft von Ruby mit der Knappheit von Scheme verbinden; weil der Parser von Lisp einfach ist, schrieb er ihn selbst und konnte verschachtelte Listen direkt behandeln.
- Wirklich verstanden habe er Lisp erst, als er FEXPR implementierte, bei denen Funktionen nicht ausgewertete Werte, sondern die Liste selbst erhalten.
- Arrays verwenden die Syntax
[1 2 3], Dictionaries die Syntax{k v}.- Das ist nicht nur Clojure- und newLisp-Nutzern vertraut, sondern auch Nutzern von Ruby, Python und JavaScript und senkt unnötige Einstiegshürden.
- Seinen C-Coding-Stil leitet er vom Linux-Kernel-Stil ab, bevorzugt aber mehr Ausrichtung und Dekoration.
- In Ruby mag er Schreibweisen näher an englischen Sätzen mit weniger Interpunktion, etwa
method 'arg'stattmethod('arg'). - Auch in Lisp reduziert er syntaktische Verschachtelung.
- Das
letvon Lone hat die Form(let (a b c d ...) body...). - Im Vergleich zum traditionellen
(let ((a b) (c d) ...) body...)hält er die Form mit abwechselnd Namen und Werten für natürlicher im Sinne der Funktionsanwendung.
- Das
Leistung und Bootstrap-Plan
- In Benchmarks liegt Lone vor allem bei der Startgeschwindigkeit vorn; Programme können schneller starten und enden, als Ruby zum Laden von Rubygems braucht.
- In vorläufigen Messungen ist es etwa 10- bis 100-mal langsamer als Python.
- Lone ist ein Interpreter auf Listenebene, ähnlich der Form in Kapitel 5.4 von SICP.
- Python und Ruby sind Bytecode-Interpreter und liegen daher in einer anderen Leistungsklasse.
- Bytecode-Kompilierung vermeidet er, weil er das Gefühl hat, dass Lisp durch die Umwandlung von Listen in Bytecode sein Wesen verliert.
- Langfristig soll der C-Interpreter als endgültige Bootstrap-Basis bleiben, während innerhalb von Lone ein JIT-Compiler geschrieben wird.
- Geplant ist, ausführbare Seiten per
mmapzu reservieren und dann Instruktionen zu erzeugen.
- Geplant ist, ausführbare Seiten per
- In einem provisorischen Vergleich mit rekursivem Fibonacci in Bash war Lone deutlich schneller, räumt aber Messverzerrungen ein, etwa weil Bash möglicherweise bei jeder Iteration Prozesse erzeugte.
- Für Skripte ist Startzeit wichtig, daher hält er den schnellen Bootstrap von Lone für nützlich.
- Wenn Hash-Tabellen schon beim Build berechnet und als C-Initialisierungsdaten erzeugt werden, ließen sich die Initialisierungskosten zur Laufzeit weiter senken.
Speicher und Minimalumgebung
mmapfordert Speicherseiten vom Kernel an; eine typische Seitengröße beträgt 4.096 Byte.- Lese-, Schreib- und Ausführungsrechte lassen sich festlegen, und JIT nutzt ausführbare Seiten.
- Wenn nur 16 Byte benötigt werden, aber 4 KiB angefordert werden, ist das verschwenderisch; deshalb nimmt ein normaler Allokator eher große Bereiche wie 128 MB und teilt sie in kleine Stücke.
- Die Top-Level-Umgebung von Lone enthält nur die zwei Symbole
importundexport.- Abgesehen von Listen, Literalen und dem Mechanismus für Funktionsaufrufe muss selbst
ifundquoteerst importiert werden. - Das Design soll dem Benutzer direkte Kontrolle über alle Namen in der Umgebung geben.
- Abgesehen von Listen, Literalen und dem Mechanismus für Funktionsaufrufe muss selbst
- Aktuell gibt es etwa 50 Funktionen, darunter
if,let,begin,control/transfer,intercept/signalundflattenals zentrale Elemente.
Standardbibliothek und Dokumentation
- Die Sprachdokumentation ist noch unvollständig, aber die Arbeit an der Standardbibliothek nähert sich mehr als die Sprachfeatures selbst.
- Als Vorbild dienen ihm die Standardbibliothek von Ruby und Benennungskonventionen aus Scheme.
- Als Nächstes steht ein Iterationsprotokoll an.
- Er denkt an eine Form wie
(for (each collection) (lambda (item) ...)). - Vorhandene
each-Funktionen sollen alle so umgebaut werden, dass sie Generatoren zurückgeben.
- Er denkt an eine Form wie
- Danach will er String-Manipulation und einen String-Builder für effiziente Verkettung implementieren.
- Wenn Iteration und String-Funktionen fertig sind, glaubt er, auch ein Web-Framework im Hiccup-Stil schreiben zu können.
- Er sorgt sich, dass seine Konzentration nach dem Abschluss der Low-Level-Arbeit und beim Übergang zu repetitiver Standardbibliotheksarbeit nachlassen könnte, und will dafür weiter Claude zur Organisation nutzen.
Das Ziel, den gesamten Stack selbst zu besitzen
- Selbst Funktionen, die mystisch wirken wie Continuations, werden zu gewöhnlichen Implementierungsproblemen, wenn man sie als Kopieren von Stack-Frames versteht; Lone soll auch andere dazu anregen, ihre eigenen Systeme zu bauen und zu erkunden.
- Er will nicht nur Konsument von Bibliotheken bleiben, sondern jemand werden, der Bibliotheken baut, und auch Systemaufrufe direkt verwenden, die gewöhnlichen Entwicklern als tabu erscheinen.
- Wer ein eigenes System haben will, muss es im Fehlerfall selbst reparieren, doch er hofft, dass mehr Menschen diese Verantwortung und Belohnung wählen.
- Man solle sich nicht vor dem angesammelten Altcode der Computergeschichte fürchten und könne unnötige Schichten entfernen.
- Vielleicht sind nicht er, sondern Rust- oder Zig-Entwickler diejenigen, die den Linux-User-Space neu bauen.
- Selbst wenn Lone keinen Erfolg hat, wäre er zufrieden, wenn es solche Versuche inspiriert.
Freie Software und Android
- Er legt Wert auf die Stärkung der Nutzerrechte, die freie Software anstrebt, und sorgt sich darüber, dass Universalcomputer zu von Unternehmen oder Regierungen kontrollierten Haushaltsgeräten schrumpfen.
- systemd bewertet er trotz eines teils schwergewichtigen Ansatzes als erfolgreiches Beispiel dafür, den traditionellen Linux-User-Space neu zu denken und neu aufzubauen.
- Er meint, man müsse seine Kämpfe wählen, statt alle Schichten selbst zu bauen.
- Wäre Lone ein Bare-Metal-Lisp geworden, hätte es womöglich nicht einmal die Boot-Phase erreicht.
- Als Beispiel nennt er jarts Sector Lisp, ein Lisp im Bootsektor mit weniger als 512 Byte.
- Lone begann in Termux und wurde zu großen Teilen auf einem Telefon geschrieben.
- Android blockiert zwar einige Systemaufrufe einschließlich
statx, dennoch läuft Lone auf Android, und die Testsuite besteht zu 100 %.
Arzt und Nicht-Berufsprogrammierer
- Moreira ist ein Arzt, der 2019 sein Medizinstudium abgeschlossen hat.
- In der Oberstufe las er über die Programmierung neuronaler Netze und entwickelte so Interesse an Biologie.
- Sein Arbeitsplan mit manchen Tagen von 10 bis 14 Stunden Sprechstunde und anderen freien Tagen schafft Raum zum Programmieren.
- In Krankenhäusern mit elektronischer Patientenakte spart er mit Vorlagen und Tippgeschwindigkeit viel Zeit.
- Er kann dokumentieren, während er Blickkontakt mit Patienten hält.
- Das kürzlich begonnene Rails-Projekt ist ein elektronisches Patientenaktensystem für seine eigenen Bedürfnisse.
- Einen Grund, warum professionelle Entwickler persönliche Probleme nicht selbst lösen, sieht er in mangelndem Interesse am Computer selbst.
- Nur auf Ergebnisse ausgerichtet zu sein reicht nicht; man braucht Neugier, um in Implementierungsdetails einzutauchen, und er weiß noch nicht, wie sich diese Neugier bei anderen wecken lässt.
1 Kommentare
Lobste.rs-Meinungen
Ich mag diese Interviewreihe so sehr, dass ich sie lückenlos lese, und besonders spannend ist es, die persönliche Beziehung zu sehen, die jede Person zum Computing aufgebaut hat.
Auch Shonumi, der Autor des GBE+- und GBA-Emulators, wurde wie ich von den Mega Man Battle Network-Spielen beeinflusst, und ich würde irgendwann gern auch sein Interview lesen.
Neustartbare Ausnahmen benötigen nicht zwingend erstklassige Fortsetzungen (first-class continuations).
Common Lisp bietet neustartbare Ausnahmen auch ohne Fortsetzungen; entscheidend ist, den Stack vor dem Aufruf des Handlers nicht zurückzuspulen.
Dadurch bleiben der Stack und der Zustand zum Zeitpunkt der Ausnahme unverändert erhalten, sodass der Handler normal zurückkehren oder – wie in Common Lisp – zu einem Restart-Handler irgendwo im Stack springen kann.
In Lone Lisp sind sie jedoch tatsächlich nötig, weil die zurückgegebene Fortsetzung mehrfach aufgerufen werden kann und aus dem Signal-Handler heraus entkommen kann. Generatoren sind die Grundlage wiederholter Verarbeitung, daher ist Performance dort wichtiger; statt begrenzter Fortsetzungen wurde ein separater Stack verwendet, um Kopien zu vermeiden.
Fehlerbehandlung ist im Vergleich dazu ein seltenerer Pfad, daher wurde entschieden, die Funktionalität vollständig bereitzustellen.
Für viele Menschen sind die wichtigsten Arbeiten oder Projekte vielleicht Dinge, die sie in ihrer Freizeit unbezahlt aus Spaß machen.
Ich stelle mir vor, dass selbst mein Arzt heimlich ein Doppelleben führen und seine eigene Lisp-Sprache bauen könnte.
Dr. Cameron Kaiser hat ebenfalls große Projekte vorangetrieben, teilt sogar eine Philosophie des Maschinenbesitzes und nutzt im Alltag eine vollständig offene POWER9-Workstation.
Ich habe diesmal zum ersten Mal von Lone Lisp gehört, und es wirkt wie ein großartiges Projekt.
Ich selbst habe mit 13 oder 14 im Informatikunterricht angefangen, C++ mit dem alten Dev-C++ zu lernen, und dass mir das nach so langer Zeit wieder einfällt, weckt Nostalgie.
Dass er Arzt ist, hätte ich überhaupt nicht erwartet, und es erinnert mich an Con Kolivas.
Offenbar gibt es überraschend viele solcher ärztlichen Entwickler.
https://en.wikipedia.org/wiki/Con_Kolivas