Der Vortrag präsentiert clj-kondo, einen schnellen und statischen Linter für die Programmiersprache Clojure. Das Tool wurde von der Aufräumphilosophie von Marie Kondo inspiriert und zielt darauf ab, fehlerhaften, überflüssigen oder unidiomatischen Code frühzeitig im Editor zu erkennen, anstatt erst in der CI-Pipeline oder in der Produktion. clj-kondo schließt die Lücke zwischen langsamen JVM-basierten Lintern (wie Eastwood) und schnellen Binär-Alternativen in anderen Sprachen (wie Joker). Es ist selbst in Clojure geschrieben, nutzt GraalVM für native und performante Startzeiten, verarbeitet Quellcode über die modifizierte Bibliothek rewrite-clj (selbst bei syntaktisch ungültigem Code) und unterstützt dateiübergreifendes Caching, Typüberprüfungen sowie umfassende Editor-Integrationen.
Wichtigste Punkte & Zeitstempel
**0:03Konzept und Namensgebung: clj-kondo ist ein statischer Linter für Clojure, der nach Marie Kondo benannt ist, um Entwicklern beim Entfernen von unnötigem oder fehlerhaftem Code zu helfen.
**1:17Motivation und Alternativen: Bestehende Alternativen wie Eastwood (auf der JVM) und Joker (in Go geschrieben) waren entweder zu langsam oder boten nicht den gewünschten Funktionsumfang, was zur Eigenentwicklung führte.
**3:03Technischer Stack und GraalVM: Das Tool nutzt Clojure und wird über GraalVM als eigenständige, extrem schnell startende Binärdatei kompiliert; zum Parsen wird eine angepasste Version von rewrite-clj eingesetzt.
**3:41Umgang mit ungültigem Code: Durch die Verwendung von rewrite-clj können auch syntaktisch fehlerhafte Strukturen (wie Maps mit doppelten Schlüsseln) als AST-Knoten geparst und mit genauen Positionsangaben versehen werden.
**6:10Dateiübergreifende Arity-Prüfung: Mithilfe eines lokalen Cache-Verzeichnisses speichert clj-kondo Signatur- und Arity-Informationen von Namespaces, um Funktionsaufrufe über verschiedene Dateien hinweg im Editor zu validieren.
**9:00Erkennung von ungenutzten Bindungen: Der Linter spürt ungenutzte Funktionsargumente, Let-Bindungen sowie Tippfehler auf, die häufig parallel zu ungenutzten Variablen entstehen.
**11:00Validierung von Testmakros: clj-kondo warnt vor Testdefinitionen ohne korrekte Prädikate oder Assertionsmakros (wie is), um unbemerkte stille Testfehler zu verhindern.
**12:48Deterministische Typüberprüfung: Das Tool führt eine zielgerichtete Typanalyse durch (z. B. Warnung bei Anwendung von first auf Transducer aus map), zieht sich jedoch bei unklaren Typen zugunsten der Vermeidung von Falschmeldungen zurück.
**15:17Konfiguration via .clj-kondo/config.edn: Über Konfigurationsdateien lassen sich Linter-Schweregrade anpassen, Ein- und Ausschlüsse steuern und unbekannte Makros per lint-as an bestehende Syntaxen (wie clojure.core/let) anlehnen.
**17:30Analyse-Export: clj-kondo kann die gewonnenen Struktur- und Code-Analysen im EDN- oder JSON-Format exportieren, sodass Entwickler eigene spezialisierte Linter oder Auswertungen darauf aufbauen können.
**18:50Community-Getriebene Makro-Unterstützung: Die Weiterentwicklung des Tools priorisiert die Unterstützung bekannter Community-Makros (z. B. Schema, defn) basierend auf direkten Nutzeranfragen und Pull Requests.
Glossar
Linter: Ein automatisiertes Softwarewerkzeug zur statischen Quellcode-Analyse, das Programmierfehler, Stilverstöße und potenzielle Bugs aufspürt.
Clojure: Eine moderne, dynamische Programmiersprache und ein Lisp-Dialekt, der auf der Java Virtual Machine (JVM) läuft und den Fokus auf funktionale Programmierung legt.
GraalVM: Eine universelle Laufzeitumgebung von Oracle, die Programme (u. a. Java und Clojure) in native, extrem schnell startende Binärdateien kompilieren kann.
rewrite-clj: Eine Clojure-Bibliothek, die Quellcode in einen bearbeitbaren Abstract Syntax Tree (AST) mit präzisen Metadaten über Textpositionen umwandelt.
AST (Abstract Syntax Tree): Ein abstrakter Syntaxbaum, der die hierarchische, syntaktische Struktur von Quellcode in einer baumartigen Datenstruktur abbildet.
EDN (Extensible Data Notation): Ein standardisiertes, leichtgewichtiges Datenformat, das eine Obermenge von JSON darstellt und im Clojure-Ökosystem primär für Datenstrukturen und Konfigurationen verwendet wird.
Arity: Die Anzahl der Argumente, die eine Funktion erwartet oder entgegennehmen kann.
Transducer: Ein funktionales Programmierkonzept in Clojure zur unabhängigen Erstellung von Transformationslogik, die auf verschiedene Datensammlungen (Collections) angewendet werden kann.
Namespace: Ein logischer Container in Programmiersprachen, der zur Isolierung von Funktions-, Variablen- und Klassennamen dient, um Namenskonflikte zu verhindern.
REPL (Read-Eval-Print Loop): Eine interaktive Programmierumgebung, die Benutzereingaben einliest, auswertet, das Ergebnis ausgibt und auf die nächste Eingabe wartet.