Elegante Lösung des Ausdrucksproblems: Mehrfachdispatch und offene Methoden

2025-09-07

Dieser Artikel befasst sich mit dem „Ausdrucksproblem“, einer Herausforderung, die sowohl die objektorientierte als auch die funktionale Programmierung betrifft: das Hinzufügen neuer Datentypen und Operationen, ohne den bestehenden Code zu ändern. Anhand von Beispielen in C++ und Haskell veranschaulicht der Autor den Kern des Problems. Traditionelle OOP hat Schwierigkeiten, Typen und Operationen gleichzeitig zu erweitern, und die funktionale Programmierung stößt auf ähnliche Einschränkungen. Der Artikel analysiert das Besuchermuster und seine Erweiterungen eingehend und verwendet schließlich die Multimethoden und Protokolle von Clojure, um zu zeigen, wie Mehrfachdispatch und offene Methoden das Ausdrucksproblem elegant lösen und flexiblen und erweiterbaren Code ermöglichen.

Mehr lesen
Entwicklung Mehrfachdispatch

Das Ausdrucksproblem: Elegante Lösungen in OOP und FP

2025-09-07

Dieser Artikel befasst sich mit dem "Ausdrucksproblem" im Software-Design: Wie fügt man neue Datentypen und Operationen hinzu, ohne bestehenden Code zu ändern? Der Autor verwendet Beispiele in C++ und Haskell, um die Grenzen der objektorientierten und funktionalen Programmierung bei der Lösung dieses Problems zu veranschaulichen. Anschließend werden elegante Lösungen unter Verwendung des Besucher-Musters und der Multimethoden und Protokolle von Clojure untersucht. Der Ansatz von Clojure nutzt geschickt die Leistungsfähigkeit offener Methoden, trennt Methodendefinitionen von Typdefinitionen und ermöglicht so eine flexible Erweiterung ohne Änderung des bestehenden Codes.

Mehr lesen
Entwicklung Ausdrucksproblem

Forth neu betrachtet: Zwei Implementierungen und Reflexionen über eine eigenartige Sprache

2025-08-28

Der Autor hat die Programmiersprache Forth, die er vor 20 Jahren zum ersten Mal kennengelernt hat, erneut untersucht. In zwei Monaten implementierte er zwei Forth-Interpreter: goforth (in Go) und ctil (in C). goforth, ein reiner Interpreter, ist einfach, aber es fehlen ihm fortgeschrittene Funktionen. ctil hingegen ähnelt eher einer traditionellen Forth-Implementierung und ermöglicht es, die Sprache mit Forth selbst zu erweitern, was ihre Leistungsfähigkeit unterstreicht. Der Autor argumentiert, dass Forths einzigartige Stärken in seinem historischen Hardware-Kontext liegen. Sein stapelbasiertes Modell macht es jedoch in modernen Kontexten weniger lesbar und weniger praktikabel und eignet sich daher besser als Lernprojekt zum Verständnis von Compilerprinzipien und virtuellen Maschinen.

Mehr lesen

Unifikationsalgorithmus: Implementierung und Anwendungen

2025-08-18

Dieser Beitrag befasst sich eingehend mit dem Unifikationsalgorithmus, einem Verfahren zum automatischen Lösen von Gleichungen zwischen symbolischen Termen. Er findet breite Anwendung in der logischen Programmierung und der Typinferenz. Ausgehend vom Mustermatching entwickelt der Beitrag das Konzept der Unifikation und liefert eine Python-Implementierung basierend auf dem verbesserten Algorithmus von Norvig. Die Implementierung umfasst Datenstrukturdefinitionen, die Kernfunktion `unify`, Hilfsfunktionen `unify_variable` und `occurs_check` sowie detaillierte Codebeispiele und Ausführungsergebnisse.

Mehr lesen
Entwicklung Unifikation

Die Elegante Verbindung zwischen Polynommultiplikation, Faltung und Signalverarbeitung

2025-05-21

Dieser Beitrag untersucht den Zusammenhang zwischen Polynommultiplikation, Faltung und Signalverarbeitung. Zunächst wird die Polynommultiplikation mithilfe von Tabellen und Diagrammen anschaulich erklärt und ihre grundlegende Natur als Faltungsoperation aufgezeigt. Anschließend werden diskrete Signale und Systeme eingeführt, wobei der Schwerpunkt auf linearen zeitinvarianten (LTI) Systemen liegt. Es wird erläutert, dass jedes Signal in eine Folge skalierter und verschobener Impulssignale zerlegt werden kann und die Antwort eines LTI-Systems mittels Faltung berechnet werden kann. Schließlich werden kurz die Eigenschaften der Faltung und ihre Beziehung zur Fourier-Transformation behandelt, wobei hervorgehoben wird, dass die Fourier-Transformation einer Faltung dem Produkt der Fourier-Transformationen ihrer Operanden entspricht, was eine effiziente Faltungsberechnung ermöglicht.

Mehr lesen
Entwicklung Polynome

Bloom-Filter: Eine probabilistische Datenstruktur für effiziente Mengenmitgliedschaft

2025-05-02

Bloom-Filter sind probabilistische Datenstrukturen, die effizient testen, ob ein Element Mitglied einer Menge ist, wobei minimaler Speicherplatz verwendet wird. Durch Hashing von Elementen an mehrere Positionen in einem Bit-Array bieten Bloom-Filter schnelle Mitgliedschaftstests, obwohl mit einer kleinen Wahrscheinlichkeit von falsch positiven Ergebnissen. Ideal für Szenarien, in denen die meisten Abfragen ein negatives Ergebnis liefern, beschleunigen Bloom-Filter die Suche erheblich. Dieser Artikel beschreibt die zugrundeliegenden Prinzipien, die Implementierung (mit einem Go-Beispiel) und die mathematische Herleitung. Ein praktisches Beispiel zeigt die Berechnung optimaler Parameter für eine Menge mit einer Milliarde Elementen und einer falsch-positiven Rate von 1 %, wobei deren Effizienz bei der Verarbeitung großer Datenmengen hervorgehoben wird.

Mehr lesen

Effiziente Transformer: Sparsely-Gated Mixture of Experts (MoE)

2025-04-20

Feedforward-Schichten in Transformer-Modellen sind oft sehr groß und verursachen einen Engpass in der Effizienz. Sparsely-Gated Mixture of Experts (MoE) bietet eine elegante Lösung. MoE zerlegt die große Feedforward-Schicht in mehrere kleinere „Experten“-Netzwerke und verwendet einen Router, um die optimale Teilmenge an Experten für die Berechnung jedes Tokens auszuwählen. Dies reduziert die Rechenkosten deutlich und verbessert die Effizienz. Dieser Beitrag beschreibt die Funktionsweise von MoE, liefert eine NumPy-Implementierung und erörtert wichtige Aspekte wie das Lastausgleichsverfahren der Experten.

Mehr lesen
Entwicklung Modelleffizienz

Kreuzentropie: Ein tiefer Einblick in die Verlustfunktion für die Klassifizierung

2025-04-13

Dieser Beitrag liefert eine klare Erklärung der Rolle der Kreuzentropie als Verlustfunktion in Machine-Learning-Klassifizierungsaufgaben. Ausgehend von informationstheoretischen Konzepten wie Informationsgehalt und Entropie wird die Kreuzentropie aufgebaut und mit der KL-Divergenz verglichen. Der Artikel schließt mit einer Demonstration der Beziehung zwischen Kreuzentropie und Maximum-Likelihood-Schätzung anhand numerischer Beispiele, wodurch ihre Anwendung im Machine Learning verdeutlicht wird.

Mehr lesen

Wunder mit vier 2en: Eine elegante Lösung für ein mathematisches Rätsel

2025-02-23

Ein scheinbar einfaches mathematisches Rätsel: Verwenden Sie nur vier 2en und beliebige mathematische Operationen, um eine beliebige natürliche Zahl zu erzeugen. Von der Arithmetik der Grundschule bis zur fortgeschrittenen Mathematik der Universität kann jeder teilnehmen. Anfangs eine scheinbar einfache Herausforderung, steigt der Schwierigkeitsgrad mit der Einführung von Exponenten, Fakultäten usw. Schließlich fand der Physiker Dirac mit Hilfe von verschachtelten Quadratwurzeln und Logarithmen eine allgemeine Lösung und löste dieses jahrhundertealte Problem elegant, selbst mit nur vier 2en.

Mehr lesen

Pythons JIT-Dekorateure: Drei Implementierungsstrategien

2025-02-03

Dieser Artikel befasst sich eingehend mit dem beliebten JIT-Dekorator-Muster in Python, insbesondere seiner Verwendung in den Bibliotheken JAX und Triton. Der Autor implementiert drei JIT-Dekorateure von Grund auf mit einem vereinfachten Beispiel: AST-basiert, Bytecode-basiert und Tracing-basiert. Der AST-basierte Ansatz manipuliert direkt den abstrakten Syntaxbaum; der Bytecode-basierte Ansatz nutzt den Python-Bytecode-Interpreter; und der Tracing-basierte Ansatz erstellt eine Ausdrucks-IR, indem er die Ausführung der Funktion zur Laufzeit verfolgt. Der Artikel beschreibt detailliert die Vor- und Nachteile jedes Ansatzes und verwendet JAX und Numba als Beispiele, um seine Strategien in realen Anwendungen zu veranschaulichen.

Mehr lesen
Entwicklung

Implementierung von Raft: Ein tiefer Einblick in den verteilten Konsens

2024-12-21

Dies ist der erste Beitrag einer Serie, die den verteilten Konsensalgorithmus Raft und seine Implementierung in Go beschreibt. Raft löst das Problem der Replikation einer deterministischen Zustandsmaschine über mehrere Server, wodurch die Verfügbarkeit des Dienstes auch bei Serverausfällen gewährleistet wird. Der Beitrag stellt die Kernkomponenten von Raft vor: die Zustandsmaschine, das Log, das Konsensmodul, die Leader-/Follower-Rollen und die Client-Interaktion. Er diskutiert die Fehlertoleranz von Raft, das CAP-Theorem und die Wahl von Go als Implementierungssprache. Künftige Beiträge werden detailliert auf die Implementierung des Algorithmus eingehen.

Mehr lesen
Entwicklung Verteilter Konsens