1 Punkte von GN⁺ 3 시간 전 | 1 Kommentare | Auf WhatsApp teilen
  • Bei Lisp geht es weniger um die Klammer-Syntax als um die Denkweise, die Sprache passend zum Problem zu erweitern; seinen wahren Wert erkennt man erst, wenn man REPL, Packages, Symbole, Conditions und Restarts beherrscht
  • Dank der Homoikonizität, bei der Code und Daten beide als Listen dargestellt werden, können Makros Code vor der Auswertung wie Daten behandeln und neue Kontrollstrukturen sowie syntaktische Abstraktionen schaffen
  • Auch ein in Common Lisp fehlendes while lässt sich mit defmacro hinzufügen; imitiert man es jedoch mit einer Funktion, werden die Argumente sofort ausgewertet, sodass body kein Code, sondern ein Wert wird
  • Lisp-Entwicklung ähnelt einer REPL-getriebenen Entwicklung, bei der Code fortlaufend in einem laufenden Prozess ausgewertet wird; Funktionen, Makros und Variablen können neu definiert werden, während sich das Programm ohne Unterbrechung weiterentwickelt
  • Wenn Spracherweiterbarkeit und Live-Systeme zusammenkommen, lässt sich erweiterbare Software bauen, die interne DSLs den Nutzern zugänglich macht; AutoLISP und Emacs sind typische Beispiele

Lisp verlangt ein anderes Programmiergefühl

  • Programmierer, die Lisp zum ersten Mal begegnen, empfinden die klammerreiche Syntax, die eigenartige Einrückung und die Art, bei format die Standardausgabe als erstes Argument anzugeben, als ungewohnt
  • Um Lisp zu lernen, reicht es nicht, Code lesen zu können; man muss auch mit Packages und Symbolen, dem Anlegen von Projekten, dem Einbinden von Libraries, der REPL sowie Conditions und Restarts umgehen können
  • Die größere Veränderung zeigt sich in der Art, wie Algorithmen aufgebaut werden
    • Lisp ermöglicht Dinge, die in anderen Sprachen schwer umzusetzen sind, und verändert auch die Form von Algorithmen
    • Der Ablauf wird: zuerst die Sprache passend zum Problem erweitern, danach das Programm in dieser Sprache schreiben
  • Das Blub-Paradox ist ein Konzept, das erklärt, warum Programmierer, die nur weniger mächtige Sprachen verwendet haben, die Stärken von Lisp nur schwer erkennen können

Erweiterbare Sprache

  • Lisp kann sich selbst erweitern; Lisp-Experten nennen es deshalb eine programmable programming language
  • Das zentrale Werkzeug ist das macro
    • Es bleibt nicht wie Makros in C, Rust oder Swift darauf beschränkt, wiederholten Code zu entfernen
    • Lisp-Makros können neue Bausteine schaffen, die Teil der Sprache werden
  • Common Lisp besitzt keinen eingebauten while-Operator, er lässt sich aber mit defmacro selbst hinzufügen
(defmacro while (condition &body body)
  `(loop while ,condition do
     (progn ,@body)))
  • Dieses while-Makro führt mehrere Anweisungen im body aus, solange condition wahr ist
    • loop ist ein Makro zum Schreiben komplexer Schleifen
    • progn führt mehrere Ausdrücke der Reihe nach aus und gibt das Ergebnis des letzten Ausdrucks zurück
  • Dadurch kann man statt (loop while ... do (progn ...)) die Form (while ...) verwenden; der Code wird kürzer und ähnelt der while-Struktur in C

Der entscheidende Unterschied zwischen Makros und Funktionen

  • Versucht man dasselbe Verhalten als Funktion fake-while umzusetzen, schlägt es fehl
(defun fake-while (condition body)
  (loop while condition do
    (funcall body)))
  • Beim Aufruf von fake-while werden die Argumente zuerst ausgewertet
    • condition wird zum Wahrheitswert t
    • (print counter) innerhalb von progn wird ausgeführt, und (decf counter) gibt 2 zurück
    • body ist kein Codeblock mehr, sondern der Wert 2
  • Anschließend erwartet funcall eine Funktion, erhält aber 2; daher tritt ein Typfehler wie The value 2 is not of type FUNCTION auf
  • Das Makro while dagegen wertet condition und body nicht sofort aus, sondern bewahrt sie auf
    • Mit macroexpand-1 lässt sich das Expansionsergebnis prüfen
    • Der Compiler erhält Code in der expandierten Form (LOOP WHILE ... DO (PROGN ...))
  • Anders als Funktionen werten Makros ihre Argumente nicht vorab aus, sondern behandeln sie als reine Daten; dadurch werden solche Transformationen möglich

Listen, S-Expressions und Homoikonizität

  • Lisp-Programme bestehen aus einer Folge von symbolic expressions, also S-Expressions
  • S-Expressions werden in zwei Arten unterteilt
    • Atom: Dateneinheiten wie Zahlen, Strings oder Symbole
    • Liste: eine Collection, die Atome oder andere Listen enthält
  • Der Name Lisp stammt von LISt Processing, und auch die Befehle, aus denen Programme bestehen, werden als Listen dargestellt
  • In Lisp sind Listen sowohl die wichtigste Datenstruktur als auch die Art, Code zu schreiben
    • Die Eigenschaft, dass Code und Daten beide als Listen dargestellt werden, heißt Homoikonizität (homoiconicity)
  • Dieselbe Liste (+ 1 2) verhält sich je nach Auswertung unterschiedlich
    • (+ 1 2) wird als Code ausgewertet und gibt 3 zurück
    • '(+ 1 2) wird nicht ausgewertet, sondern unverändert als Datenliste zurückgegeben
  • Lisp verwendet die polnische Notation, bei der der Funktionsname als erstes Element der Liste steht und danach die Argumente folgen
  • Weil die Grenze zwischen Code und Daten dünn ist, können Makros Quellcode transformieren und Programme schreiben, die Programme schreiben

Code-Abstraktionen durch Makros

  • Wenn man die Sprache erweitert, kann man für bestimmte Programmbereiche ausdrucksstärkere neue Bausteine schaffen
  • Wiederkehrender Boilerplate-Code lässt sich durch eigene Makros ersetzen, wodurch Code reduziert und Zeit gespart wird
  • Man kann neue Kontrollstrukturen schaffen, um Ressourcenzugriff und die Auswertung von Forms zu steuern
  • Makros erzeugen Code, verbessern die Performance und bieten syntaktische Abstraktionen, die komplexen und fehleranfälligen Code verbergen

Lisp ist ein Live-System

  • Lisp wird weniger als bloße Programmiersprache behandelt, sondern als laufendes Live-System
  • In üblichen Sprachen schreibt man Code oft zunächst im Editor, kompiliert und führt ihn dann aus, um ihn zu beobachten, zu testen und zu debuggen
  • In Lisp startet man zuerst einen Lisp-Prozess, verbindet sich mit der REPL und lädt das Projekt in diesen Prozess
  • REPL steht für Read-Eval-Print Loop und bezeichnet eine interaktive Umgebung, in der Code ausgewertet wird und man sofort das Ergebnis sieht
    • Sie dient als Fenster in den Lisp-Prozess, der das aktuelle Programm ausführt
  • Lisp-Entwickler werten im laufenden Prozess fortlaufend Code aus und prüfen die Ergebnisse direkt in der REPL
    • Testen einzelner Funktionen
    • Datenbankabfragen
    • Untersuchen von Variablen
    • Auch Aufgaben wie Debugging lassen sich in der REPL erledigen
  • Der Lisp-Prozess muss nicht angehalten werden und kann wochenlang leben
  • Funktionen, Makros und Variablen werden in der internen Speicherumgebung, der Environment, kontinuierlich definiert und neu definiert; dieser Ablauf wird REPL-getriebene Entwicklung genannt

Hot Reloading in Lisp

  • Im Web-Frontend ist die Erfahrung verbreitet, dass JavaScript-Code durch Speichern von Dateien oder Neuladen der Seite hot-reloaded wird
  • Übliches Hot Reloading hängt von separaten Tools und Techniken ab, etwa File Watching, dem Neukompilieren geänderter Module oder dem Einspeisen von Änderungen über WebSockets
  • Nicht jeder Software-Stack bietet Hot Reloading auf demselben Niveau
    • Einige Backend-Frameworks benötigen eine Neukompilierung
    • Bei Desktop- und Mobile-Entwicklungsumgebungen ist die Lage gemischt
    • Low-Level-Sprachen erfordern jedes Mal eine vollständige Kompilierung
  • In Lisp ist Hot Reloading kein separates Tool, sondern ergibt sich in der Live-Umgebung natürlich daraus, dass Code ausgewertet wird
    • Wenn man ein Symbol neu definiert, verwenden Funktionen, Daten und Makros alle die neue Definition
    • Die Notwendigkeit, anzuhalten und zu kompilieren, Tests separat auszuführen oder einen speziellen Debugger zu verwenden, nimmt ab
  • Lisp-Programmierung ähnelt eher dem Weiterentwickeln eines Programms als seinem Zusammenbauen

Erweiterbare Software

  • Spracherweiterbarkeit und Live-Systeme machen es in Lisp leicht, erweiterbare Software zu bauen
  • Übliche Desktop-Programme werden über Plugins oder Skriptsprachen erweitert
    • Entwickler müssen ein Erweiterungssystem entwerfen und warten
    • Nutzer müssen eine bestimmte API lernen, um Plugins oder Erweiterungen zu schreiben
  • In Lisp schreibt man ganz natürlich DSLs, während man Verhalten mit Makros kapselt und leichter wiederverwendbar macht
  • Um Software erweiterbar zu machen, genügt es, die intern erstellte DSL den Nutzern zur Verfügung zu stellen
  • Im Beispiel eines CMS-Servers könnte man den Nutzern ein html-Makro zur serverseitigen Erzeugung von Webseiten zugänglich machen
    • Nutzer können Lisp-Variablen, dolist-Schleifen und String-Formatierung mit format unverändert gemeinsam verwenden
    • Es ist nicht nötig, wie bei klassischen Template-Sprachen eine eigene Syntax wie {{ user_name }} oder {% for %} zu lernen
  • Diese DSL erbt direkt die Fähigkeiten von Lisp für Bedingungen, Rekursion, Funktionen höherer Ordnung und schrittweises Debugging in der REPL
  • Im Beispiel einer Software für mathematische Graphen könnte man eine DSL für Formeln und Zeichnungen bereitstellen, mit der Nutzer Kurven und Punkte mit wenig Code zeichnen können

Praxisbeispiele und Lisps Position

  • AutoCAD verwendet AutoLISP zur Automatisierung wiederkehrender Aufgaben und zur Erzeugung komplexer Geometrien
  • Emacs ist ein Texteditor, der größtenteils in seinem eigenen Lisp-Dialekt implementiert ist und dadurch hohe Erweiterbarkeit erreicht
    • PDF-Reader
    • Webbrowser
    • E-Mail-Client
    • RSS-Reader
    • Terminal-Multiplexer
    • Git-Client
    • Musikplayer
    • Chat-Client
    • Tabellenkalkulation
    • IRC-Client
    • sogar ein Desktop-Fenstermanager wird als erweitertes Beispiel aufgeführt
  • R. M. Stallman bewertet Lisp als eine Sprache, die verstehen lässt, was eine mächtige und elegante Programmiersprache bedeutet
  • Die Erwartung, dass Lisp eines Tages so breit wie eine Standardsprache genutzt würde, hat sich nicht erfüllt, und es wirkt unwahrscheinlich, dass dies künftig geschieht
  • Dennoch hat Lisp seit den 1960er-Jahren überlebt und ist nach Fortran zur ältesten noch aktiven Programmiersprache geworden
  • Der Wert von Lisp liegt nicht in einer einzelnen Funktion wie Erweiterbarkeit, interaktiver Umgebung oder REPL, sondern in deren Kombination

1 Kommentare

 
GN⁺ 3 시간 전
Hacker-News-Meinungen
  • Programmieren steht im Spannungsfeld zwischen der hellen Seite und der dunklen Seite
    Die helle Seite will verhindern, dass Programmierer Fehler machen: goto abschaffen, statische Typen einführen, Bugs unausdrückbar machen usw.
    Die dunkle Seite gibt Programmierern Macht: Makros, Operator-Overloading, selbstmodifizierender Code, sogar mehrzeilige reguläre Ausdrücke sind nach Belieben erlaubt.
    Lisp ist eindeutig die dunkle Seite, weil Programmierer damit alles tun können, und trotzdem ist interessant, dass es auch von Programmierern der hellen Seite respektiert wird. Vielleicht wirkt die Einfachheit der Sprache platonisch und nahezu unkorrumpierbar, oder Lisp ist so rein, dass es wie ein Gott, der das Programmieruniversum hervorgebracht hat, beide Seiten in sich vereint.

    • Um eine Aussage aus der Debatte um dynamische und statische Typen abzuwandeln: permissive Sprachen geben Einzelentwicklern Macht, aber Teamentwicklung braucht stärker einschränkende Sprachen.
      Man kann sich die Leute, mit denen man zusammenarbeitet, nicht aussuchen, und das Können im Team ist ungleich verteilt. Wenn weniger erfahrene Kollegen Fehler machen, werden die Folgen umso größer, je permissiver die Sprache ist.
      Deshalb braucht man Code-Reviews, aber damit macht man erfahrene Programmierer zu Lehrern. Ein Teil der Zeit, die man darauf verwendet, andere Programmierer besser zu machen, ist deshalb verschwendet, weil Programmierer jederzeit kommen und gehen können. KI könnte dieses Gefüge verändern.
      Letztlich geht es darum, kleine, erfahrene Teams zu erhalten, aber wegen Unternehmenspolitik ist das nicht leicht. Häufig kommt zum Beispiel der Ansatz auf, wegen des Bus-Faktors oder zur Verkürzung der Release-Zeiten mehr Entwickler hinzuzuziehen.
    • Lisp hat im Allgemeinen exakte Garbage Collection, daher könnte man es auch eher der hellen Seite zurechnen. Wenn man Runtime-Type-Checks als Typsicherheit gelten lässt, ist es auch ziemlich typsicher.
      Hochzuverlässige Systeme werden auch in Erlang geschrieben, das man mit etwas zusammengekniffenen Augen als einen weiteren Lisp-Dialekt sehen kann. Es gibt mit LFE auch eine auf S-Expressions basierende Version, also ein Lisp-artiges Erlang.
      Der Kern der Zuverlässigkeit von Erlang liegt nicht in außergewöhnlicher Fehlervermeidung, sondern in Fehlerwiederherstellung. Die Einteilung in hell/dunkel gefällt mir an sich.
    • Ein großes Merkmal von Lisp ist meiner Ansicht nach, dass es, abgesehen von veränderlicher Variablenzuweisung, grundsätzlich deklarativ ist und nicht dem imperativen Paradigma folgt.
      Auch wenn es keine statischen Typen hat und Makros im Chaos enden können, ist die Grundlinie deklarativen und funktionalen Denkens deutlich stärker, was einen besseren Ausgangspunkt bietet, um Programme klarer zu denken und über sie zu schlussfolgern.
    • Ich frage mich, auf welche Seite man Malbolge stellen würde. Und Python, Haskell, Idris, Clean, C, K?
      Die Unterscheidung zwischen hell und dunkel wirkt zu stark vereinfacht. Die Balance von Programmiersprachen ist ein sehr komplexes und interessantes Thema.
      Nachdem ich über Jahre mit verschiedenen Sprachen experimentiert habe, lief es am Ende auf Nutzungskontext, persönliche Vorlieben und Ziele hinaus. Es gibt nicht „die beste Programmiersprache aller Zeiten“, und auch nicht „die beste für Programmieren auf der hellen Seite“ oder „die beste für Programmieren auf der dunklen Seite“.
      Auch in der Kunstmalerei gibt es keine helle oder dunkle Seite. Es gibt sicher größere Gemälde, aber kein „bestes Gemälde“, das jeder im Vergleich zu allen anderen Bildern als das schönste empfinden würde.
      https://en.wikipedia.org/wiki/Malbolge
      https://en.wikipedia.org/wiki/Clean_(programming_language)
      https://en.wikipedia.org/wiki/K_(programming_language)
    • Es scheint, als seien hell und dunkel vertauscht. Zwang und Disziplin nach dem Motto, der Schöpfer wisse es am besten, sind die dunkle Seite; dem Menschen Macht anzuvertrauen ist die helle Seite.
  • In den letzten Monaten sind großartige neue Editoren und Tools erschienen, die man nicht verpassen sollte.
    Mine ist eine App als einzelner Download und bietet alles, was man braucht, um einen interaktiven, inkrementellen Entwicklungsfluss zu erleben, einschließlich Hot Reloading und Debugging direkt vor Ort. Für CL und Coalton.
    https://coalton-lang.github.io/20260424-mine/
    OLIVE ist ein handgemachtes Plugin für VSCode, und ICL ist eine neue REPL für Terminal und Browser mit erweiterten Funktionen. Als Bonus gibt es auch einen JSCL-basierten JupyterLite-Kernel, der zu 100 % im Browser läuft.
    Alles ist hier zu finden: https://lispcookbook.github.io/cl-cookbook/editor-support.ht...

    • Ich kann den Source von mine nicht finden. Gibt es einen Link?
  • Auf der Website scheint es einen Bug beim Syntax-Highlighting zu geben. Die im Text eingebetteten Codefragmente erscheinen schwarz; wenn man sie mit der Maus markiert, sieht man den tatsächlichen Text.
    Ich sehe denselben Bug in Chrome auf dem Desktop und in Safari auf dem iPad.

    • Ein klassischer Fall dafür, dass man beim Ändern der Hintergrundfarbe immer auch die Vordergrundfarbe festlegen muss. Sonst bekommt man schwarze Textblöcke auf schwarzem Hintergrund. Wenn der Browser im Dark Mode ist, wird es vermutlich normal aussehen.
      Ein Workaround ist, im Browser-Debugger ein Code-Element zu öffnen und dem Stil :not(pre) > code color: white hinzuzufügen.
    • Ich habe den Fehler behoben, sobald ich den Kommentar gelesen hatte.
    • Ist das macOS Chrome? Unter Linux sehen die Codeblöcke in Firefox, Chromium und Brave normal aus. Vermutlich nutzen sie alle Qt.
    • Dasselbe Phänomen tritt sowohl in Firefox als auch in Chrome auf.
    • Zuerst dachte ich, der Text sei zensiert worden.
  • Es gibt viele Texte, die die Vorzüge von Lisp preisen. Ich würde gern auch Texte sehen, die Lisp, seine Ideen und seine Stellung im Sprachökosystem ruhig und sachlich kritisieren.
    Solche Texte oder die hier referenzierten Texte von PG laufen am Ende auf „wer es weiß, der weiß es“ hinaus. Ich verstehe den Reiz, und ich verstehe auch die expliziten und impliziten Behauptungen dieses Textes.
    Computerprogrammierung ist in den vergangenen 60 Jahren ziemlich gereift. Ich würde gern mehr Texte mit einer stärker durchdachten Prüfung sehen.

    • Als Sprache ist Lisp großartig, aber das Ökosystem ist begrenzt. Es gibt zwei Schwächen. Die eine ist, dass es zu offen ist: Ohne Talent und Disziplin kann man in den Kaninchenbau interessanter Lisp-Hacks geraten und die eigentliche Arbeit nicht fertig bekommen. Andere Sprachen haben dieses Problem auch, aber ich denke, bei Lisp ist es stärker ausgeprägt.
      Die zweite Schwäche ist, dass es die Zeit ausreichend fähiger Leute über Jahre verschlingt, die Ergebnisse diese investierte Zeit aber nicht rechtfertigen. Dinge wie Python reichen ebenfalls aus. Ich denke, es wäre besser gewesen, den Großteil der in Lisp investierten Zeit anderswo einzusetzen.
    • Die Formulierung „Programmierung ist ziemlich gereift“ klingt, als würde Lisp irgendwo in der Vergangenheit stehen geblieben sein.
      Clojure, Clojurescript, Clojure-Dart, Fennel, Jade, Jank, Jolt und Coalton sind relativ junge Sprachen und entwickeln sich weiterhin. Das sind nur die, die mir gerade einfallen, es gibt noch viel mehr.
      Lisp ist in gewissem Sinne keine Programmiersprache, sondern eine Idee. Es hat fast alle Programmiersprachen beeinflusst, die wir heute verwenden, und tut das weiterhin. Eine Idee „ruhig und sachlich“ zu kritisieren ist schwierig, ähnlich wie Gruppentheorie zu kritisieren. Man kann aber über die Vor- und Nachteile bestimmter Implementierungen dieser Idee sprechen.
    • Der Fluch von Lisp: https://www.winestockwebdesign.com/Essays/Lisp_Curse.html
    • Für eine heutige Sprache ist standardisierte Nebenläufigkeit eine Grundvoraussetzung. CL hat kein standardisiertes async/await und kein standardisiertes Nebenläufigkeitsmodell. Der Standard wurde seit 1995 nicht aktualisiert, also wird das wohl auch nicht mehr passieren.
    • Lisp scheint so etwas wie eine bestimmte Griffausrichtung zu haben.
      Für manche Menschen wirkt es geistig anziehend. Ich würde es mit einem wirklich nischigen Musikgenre vergleichen. Nur wenige mögen es, aber diese Leute mögen es äußerst intensiv. Es ist so etwas wie Stockhausen in der Programmierwelt.
      Im Grunde ist es ein Fandom. Ein erstaunlich langlebiges Fandom, aber es ist nie breit durchgebrochen, und es ist unwahrscheinlich, dass das noch passiert. Heute ist seine Position sogar schlechter. Wenn man mit LLMs bewaffnet ist und einem der Code selbst nicht besonders wichtig ist, warum sollte man es dann ausgerechnet anweisen, in Lisp zu schreiben?
  • Ich habe so lange Lisp gemacht, dass ich seine Funktionen nicht mehr richtig zu schätzen wusste. Wenn man dann mit Schock und Schrecken sieht, wie Leute sich in populären und wirtschaftlich weniger riskanten Sprachen selbst ins Verderben stürzen, spürt man plötzlich wieder den Wert von Lisp.

  • In kommerziellen Umgebungen sind domänenspezifische Sprachen ein Antipattern. Jemand baut eine schlecht dokumentierte domänenspezifische Sprache, die nur er selbst versteht, und geht dann weg.
    Die nachfolgenden Programmierer müssen sich abmühen, diese seltsame Sprache zu entschlüsseln. Fast immer ist es besser, standardisierte Sprachstrukturen und -funktionen zu verwenden. Code wird häufiger gelesen als geschrieben.

    • Jedes Mal, wenn man eine Funktion erstellt, baut man gewissermaßen eine eigene Sprache, die auf diese Domäne zugeschnitten ist.
      Wogegen man sich tatsächlich wendet, ist wahrscheinlich eher ein Mangel an referenzieller Transparenz. Fairerweise ist das in vielen Sprachen ein Problem, einschließlich Lisp.
    • In Lisp können die nachfolgenden Programmierer einfach die Makroexpansion ansehen. Mit modernen Tools geht das auf Wunsch im Editor, als Ersatztext in derselben Quelldatei und verbunden mit einer laufenden Lisp-Umgebung.
      Ein gutes Beispiel ist das LOOP-Makro von Common Lisp selbst. Wenn die Verwendung durch jemanden schwer zu verstehen ist, kann man Lisp bitten, sie in ausführlichere grundlegende Aufrufe ohne LOOP zu expandieren, und man muss LOOP überhaupt nicht verstehen. Tatsächlich kann man die LOOP-Form sogar durch den expandierten Code ersetzen.
      Das ist ein zentraler Unterschied zu den meisten anderen Sprachen, in denen Code für domänenspezifische Sprachen tatsächlich eine interpretierte Datenstruktur ist.
  • Lisps haben wirklich mächtige und einzigartige Eigenschaften, aber ich wünschte, solche Texte würden REPL und Hot Reloading nicht ständig dazuzählen.
    REPLs sind bei interpretierten Sprachen, ja sogar bei einigen kompilierten Sprachen, schon seit Langem eine Grundvoraussetzung. Hot Reloading ist weder einzigartig noch besonders weit verbreitet. Da man Zustand und Patches handhaben muss, gibt es einen Grund dafür, dass es als Best Practice gilt, alles zurückzusetzen, um das Schlussfolgern zu erleichtern.

    • Als ich Clojure lernte, dachte ich das auch. Erst viel später wurde mir klar, dass Lisp-Leute mit REPL meist nicht eine interaktive CLI meinen, in der man Befehle einfach auswertet, sondern die Fähigkeit, ein Programm mit einer lebenden Session zu verbinden, sodass man Forms im Kontext der laufenden Anwendung schnell aus dem Texteditor heraus auswerten kann.
      Dadurch wird eine viel interaktivere Entwicklung möglich als bei anderen interpretierten Sprachen.
    • In Dart/Flutter wird Hot Reload sehr breit genutzt. Wenn man UI-Code mit einem Framework im reaktiven Stil schreibt und das UI-Rendering so wirkt, als würde „in jedem Frame eine neue UI von Grund auf erzeugt“, ist es leichter, eine Intuition dafür zu haben, was neu geladen wird und was nicht.
      Natürlich ist es nicht perfekt. Aber für die Art von Änderungen, die man bei iterativen Verbesserungen der User Experience vornimmt, funktioniert es sehr gut.
    • Im Großen und Ganzen stimme ich zu.
      Allerdings ist erwähnenswert, dass ein großer Teil der fortgeschrittenen Aspekte von Hot Reloading in Common Lisp bereits behandelt wurde. Ebenso, dass die REPL weniger als Ort zum direkten Tippen genutzt wird, sondern vor allem als sehr mächtige Schnittstelle, über die Tools mit einem laufenden Image interagieren.
      Trotzdem stimme ich zu, dass die bloße Existenz dieser Dinge heute nicht besonders außergewöhnlich ist.
    • Nicht alle Lisp-Dialekte haben ein gut entwickeltes Hot-Patch-System. Objektorientierte Systeme müssen dafür sorgfältig entworfen sein.
      Was passiert, wenn eine Klassendefinition per Reload ersetzt wurde, aber bestehende Instanzen übrig bleiben? Common-Lisp-Dialekte haben nützliche Antworten auf solche Fragen, aber nicht jedes Lisp, dem man begegnet, hat sie zwangsläufig.
      Auch Bash unterstützt Hot Reloading. Ich habe schon Module entwickelt, die man wie folgt per source an Ort und Stelle aktualisiert:
      $ . /path/to/script.sh
    • Im Allgemeinen hängen die Schmerzen beim Umgang mit Hot Patches stark von der Struktur der Codebasis und dem Grund ab, aus dem man Hot Patching betreiben will. Bei einer Array-Structure-Architektur oder beim Beheben logischer Laufzeitfehler ist das keine große Sache.
      Der Nutzen ist begrenzt, aber wenn man mit der Annahme beginnt, dass man es viel verwenden wird, verschwinden diese Grenzen ziemlich schnell.
  • Persönlich bin ich über diese Phase hinaus. Ich habe Common Lisp, Forth und Haskell ausprobiert und 『On Lisp』 sowie 『Let Over Lambda』 mit Vergnügen gelesen.
    Heute denke ich, dass die beste Programmiersprache Barry Jays Triage Calculus ist. Er ist der kombinatorischen Logik oder dem untypisierten Lambda-Kalkül ähnlich.
    Anders als der Lambda-Kalkül hat der Triage Calculus jedoch eingebaute Quotierung und Introspektion, ähnlich wie Lisps CAR und CDR, sodass sich Typprüfung leicht hinzufügen lässt. Deshalb kann man in TC jede gewünschte Syntax haben, solange man nur die richtigen Abstraktionen baut. Es ist die wirklich ultimative Programmiersprache.
    TC zeigt, dass die Trennung zwischen Programmiersprachen-Features und Syntax auf der einen Seite und Funktions-/API-Definitionen in Standardbibliotheken oder User-Code auf der anderen eine falsche Dichotomie ist. Jedes Mal, wenn man Code schreibt, der zur Wiederverwendung gedacht ist, fügt man der Sprache etwas hinzu. All das lässt sich als irgendein Term in TC ausdrücken.
    Alle Syntax-Debatten sind eine Frage der Gewohnheit. Das einzige Syntax-Feature, das ich mir in TC wirklich wünsche, ist allerdings eine let over lambda-Abstraktion, weil es etwas lästig ist, Kombinatoren von Hand anzuordnen.

  • Gut geschriebener Artikel.
    Früher dachte ich, dass irgendwann alle Lisp verwenden würden und alles großartig wäre, sobald es gute Tools und Bibliotheken gäbe. Mein tatsächlicher Plan für den Ruhestand war sogar, hochwertige Bibliotheken für Lisp-Sprachen zu erstellen, um diesen Prozess zu beschleunigen.
    Wird der Aufstieg der KI diesen Traum beenden? Haben wir das Problem wieder einmal gelöst, indem wir einfach noch mehr Gerümpel hinzugefügt haben? Wird eine superintelligente KI, statt Code in der bestmöglichen Programmiersprache zu schreiben, einfach massenhaft Python-Code ausspucken und so lange weitermachen, bis es funktioniert?
    Ich weiß nicht, ob das wichtig ist. Ich wollte einfach eine Welt mit Eleganz.

    • Ich habe mich immer gefragt, was aus dem ersten „Interface Builder“ geworden wäre.
      „Jean-Marie Hullot entwickelte während seiner Arbeit bei INRIA das in Lisp geschriebene ‚SOS Interface‘ für den Macintosh, den ersten modernen ‚Interface Builder‘.“
      https://denninginstitute.com/itcore/userinterface/GUIHistory...
      Ich frage mich, wie es gewesen wäre, wenn das ein Mainstream-Mac-Produkt geworden wäre, statt zu NeXT zu wandern und zusammen mit Objective-C verwendet zu werden.
      LISP passte gut zu mir. In einem Vergleichskurs zu Programmiersprachen an der Uni war ich der Einzige, der alle LISP-Aufgaben geschafft hat, und LISP zu lernen half mir auch sehr bei der Nutzung von TeX.
      Was ich mir wünsche, ist ein ordentliches Open-Source-GUI-Toolkit, nativ oder Cross-Plattform, und eine einfache Möglichkeit, Projekte als eigenständig ausführbaren kompilierten Code auszuliefern.
    • Die Sprache ist nie die Antwort. Lisp ist Visual Basic nicht überlegen. Beide sind Turing-vollständig.
      Menschen können mit beiden gute Ideen ausdrücken. Es ist besser, Sprachen als Werkzeuge zu betrachten. Ein Schlagbohrer ist einem einfachen Rotationsbohrer nicht überlegen. Wenn man eine Terrasse baut, passt ein Schlagbohrer vielleicht besser, aber beide können die Arbeit erledigen.
  • Ich dachte, dieser Artikel wäre https://web.archive.org/web/20120106121645/http://wiki.alu.o....
    Das erinnert mich daran, wie ich comp.lang.lisp verfolgt habe. Es war irgendwie auch ein Drama. Nicht nur Programmiermagie, sondern auch viele markante Persönlichkeiten und Ereignisse.