Datalog ist eine deklarative Logikprogrammiersprache, die Ende der 1970er-Jahre als Abfragesprache für deduktive Datenbanken entstand. Sie ist syntaktisch eine Teilmenge von Prolog, verwendet aber ein anderes Auswertungsmodell: Datalog arbeitet bottom-up (von den Fakten zu den abgeleiteten Aussagen) und garantiert Terminierung, weil Rekursion auf monotone Mengen beschränkt ist.
Programmstruktur: Fakten, Regeln, Abfragen
% Fakten (Extension)
elternteil(anna, ben).
elternteil(ben, carla).
% Regeln (Intension)
vorfahre(X, Y) :- elternteil(X, Y).
vorfahre(X, Z) :- elternteil(X, Y), vorfahre(Y, Z).
% Abfrage
vorfahre(anna, X)?
Ein Datalog-Programm besteht aus Fakten (grundlegende Beziehungen), Regeln mit Horn-Klauseln (Kopf :- Rumpf) und Abfragen. Das Beispiel berechnet den transitiven Abschluss der Elternbeziehung — ein klassisches Muster, das in SQL erst über rekursive Common Table Expressions möglich ist.
Werkzeuge
souffle program.dl # Soufflé: Datalog zu nativem C++ kompilieren
souffle program.dl -F fakten/ -D ergebnis/ # Fakten-Eingabe, Ausgabe-Verzeichnis
python3 -m pip install pyDatalog # pyDatalog: Datalog in Python
Soufflé ist die bekannteste moderne Implementierung: Es übersetzt Datalog in paralleles C++ und wird vor allem in der statischen Analyse eingesetzt (z. B. Points-to-Analyse für Java). pyDatalog bringt die Logikprogrammierung nach Python, Datalog-basierte Regeln stecken außerdem in Datenbank-Erweiterungen wie dem LogicBlox-System und in Analyseverfahren vieler Compiler.
Eigenschaften
- Negation ist nur in stratifizierter Form erlaubt (keine Negation in Rekursionszyklen), damit das Ergebnis eindeutig bleibt.
- Die Trennung in Extension (EDB: Fakten) und Intension (IDB: Regeln) erinnert an Views über Basistabellen.
- Datalog ist deterministisch und terminierend — anders als Prolog gibt es keine Suchreihenfolge und kein Backtracking.
Verwandte Themen: Prolog-Befehle zeigen die Top-down-Variante der Logikprogrammierung, SQL-Befehle die klassische Datenbankabfrage, Python-Befehle die Einbindung über pyDatalog. In der Welt der deklarativen Datenverarbeitung ergänzt jq die JSON-Seite: Dort fragt man Datenstrukturen deklarativ ab, Datalog fragt Faktenmengen ab.
jq ist ein schlankes Kommandozeilen-Werkzeug zum Filtern, Transformieren und Formatieren von JSON-Daten. Entwickelt von Stephen Dolan (erste Veröffentlichung 2012), wird jq oft als „sed für JSON“ bezeichnet: Es liest JSON von der Standardeingabe oder aus Dateien, wendet einen Filterausdruck an und schreibt das Ergebnis als JSON auf die Standardausgabe.
Grundlagen
jq '.' datei.json # JSON hübsch formatiert ausgeben
echo '{"name":"Ada"}' | jq '.name' # Feld extrahieren
jq -r '.name' datei.json # -r: Roh-String ohne Anfuehrungszeichen
jq -c '.' datei.json # -c: kompakte Einzeilen-Ausgabe
Der Punkt . steht für das aktuelle Objekt. Mit .feld greift man auf ein Feld zu, mit .[] iteriert man über ein Array. Die Pipe | im Filter (nicht die Shell-Pipe) verkettet Ausdrücke.
Häufige Filter
jq '.users[] | select(.age > 30)' datei.json # filtern
jq '.users | map(.name)' datei.json # Feld je Element
jq 'length' datei.json # Anzahl / Länge
jq 'keys' datei.json # Objekt-Schlüssel
jq 'sort_by(.preis) | reverse' datei.json # sortieren
jq '.items[0:3]' datei.json # Slice
jq -s '.' *.json # -s: alle Eingaben als Array
Mit select() und map() lassen sich typische API-Antworten direkt in der Pipeline aufbereiten, zum Beispiel curl -s https://api.example.com/items | jq '.items[].name'.
Praxis-Tipps
- Filter immer in einfache Anführungszeichen setzen, damit die Shell keine Zeichen frisst.
jq '.[] | .name'liefert mehrere Werte als Stream; mit-reignen sich die Ausgaben direkt fürwhile read-Schleifen.- Das Format JSON selbst ist im Glossar unter JSON erklärt, weitere Datenformate unter YAML, TOML und JSON.
Verwandte Werkzeuge: Für YAML-Konfigurationen übernimmt yq die gleiche Rolle, in Shell-Pipelines ergänzen Bash-Befehle und curl/wget die Arbeit. Wer Daten deklarativ abfragen will, findet in Datalog das logikbasierte Gegenstück zu den JSON-Filtern.
newLISP ist ein von Lutz Mueller entwickelter Lisp-Dialekt, der seit 1991 als Skriptsprache konzipiert ist. Dank geringer Ressourcenanforderungen eignet er sich auch für eingebettete Systeme. newLISP reduziert Lisp auf seine Kernkomponenten Listen, Symbole und Lambda-Ausdrücke und nutzt ein ungewöhnliches Ein-Referenz-Speichermodell, das die Speicherverwaltung stark vereinfacht.
Erste Schritte
newlisp # interaktive REPL
newlisp skript.lsp # Skript ausführen
Wichtige Befehle
- Funktionen & Variablen:
define,set,setq,lambda,fn - Listen:
push,pop,assoc,lookup,slice,map,apply,filter - Kontrollfluss:
dolist,dotimes,if,cond,when,until - Kontexte:
context— ein Kontext mit Default-Funktor arbeitet wie eine Funktion mit Speicher, etwa als Wörterbuch - Netzwerk:
net-listen,net-eval,net-send,net-receive - Text:
println,print,regex,replace
Ein Kontext als Wörterbuch: (new Class 'Wortbuch) erzeugt einen eigenen Namensraum; Einträge liest man mit (assoc "Schluessel" (Wortbuch)).
Verwandte Grundlagen: PicoLisp-Befehle, Common-Lisp-Befehle und Hy-Befehle.
Hy (auch hylang) ist ein Lisp-Dialekt, der direkt in Python eingebettet ist: Der Hy-Compiler transformiert Lisp-Code in Python-Abstract-Syntax-Tree-Objekte (AST). Dadurch stehen Programme in Lisp-Form die gesamte Python-Welt — Bibliotheken, Objekte und Ökosystem — offen. Hy wird per pip install hy installiert und ist seit 2013 aktiv gepflegt.
Erste Schritte
hy # interaktive REPL
hy skript.hy # Skript ausführen
Wichtige Befehle
- Funktionen & Variablen:
defn,defclass,setv,fn,lambda - Makros:
defmacro, Threading-Makros->und->>aus Hyrule - Kontrollfluss:
if,when,cond,for,while,try - Listen & Iteration:
list-comp,map,filter,reduce,loop - Python-Interop:
import,print,get,setv
Hyrule ist die mitgelieferte Utility-Bibliothek — das Hy-Äquivalent zur Python-Standardbibliothek. Ein einfaches Beispiel:
(defn quadrat [x]
(* x x))
(print (quadrat 7))
Verwandte Grundlagen: Python-Befehle, PicoLisp-Befehle und newLISP-Befehle.
PicoLisp ist ein minimalistischer Lisp-Dialekt, den Alexander Burger seit den 1990er-Jahren entwickelt. Die Sprache lebt als Interpreter, der weitgehend in PicoLisp selbst geschrieben ist, und bildet Lisp-Kernkonzepte 1:1 auf eine schlanke virtuelle Maschine ab. Neben der Nutzung als allgemeine Programmiersprache dient PicoLisp auch als Application-Server-Framework mit eigener Datenbank (Pilog).
Erste Schritte
Der Interpreter heißt pil. Argumente, die mit einem Bindestrich beginnen, werden direkt evaluiert, alle anderen als Datei geladen:
pil app.l -main
pil -'println (mapcar + (1 2 3))'
Wichtige Befehle
- Listen-Grundlagen:
car,cdr,cons,quote(Kurzform') - Variablen & Kontrolle:
setq,let,do,loop,if,cond - Funktionen höherer Ordnung:
mapcar,apply,filter - Ausgabe & Laden:
println,print,load,eval - Wahrheitswerte:
TundNIL
PicoLisp definiert bewusst keine festen Kommandozeilen-Flags — jede Anwendung kann eigene Optionen über die Interpreter-Argumente festlegen.
Verwandte Grundlagen: Common-Lisp-Befehle, newLISP-Befehle und Hy-Befehle.