- OxCaml ist ein Erweiterungsset, das OCaml um leistungsorientierte Funktionen ergänzt
- Es ist Jane Streets Produktions-Compiler und dient zugleich als Experimentierlabor für künftige Funktionen von OCaml
- Es zielt darauf ab, Sicherheit, Bedienkomfort und Vorhersehbarkeit in den Mittelpunkt zu stellen und die Kontrolle über die Performance zu erweitern
- Es bietet Funktionen in verschiedenen Bereichen wie Fearless concurrency, Layout-Kontrolle und Allokationskontrolle
- Es wird als Open Source bereitgestellt, sodass experimentierfreudige Nutzer und Forschende es frei testen und Feedback geben können
Einführung in OxCaml
Was ist OxCaml?
- OxCaml ist eine sich schnell weiterentwickelnde Sammlung von Erweiterungen für die Programmiersprache OCaml
- Es ist Jane Streets Compiler für den Praxiseinsatz und zugleich eine experimentelle Plattform zur Stärkung performanceorientierter Programmierung in OCaml
- Das Ziel ist, diese Erweiterungen langfristig zu offiziellem OCaml beizutragen
Zentrale Designziele von OxCaml
- Ziel ist es, eine Umgebung bereitzustellen, in der sich die leistungsbestimmenden Faktoren des Programmverhaltens sicher, komfortabel und vorhersehbar steuern lassen
- Diese Kontrolle wird nur dann optional bereitgestellt, wenn sie wirklich notwendig ist
- Alles wird innerhalb der OCaml-Umgebung implementiert
Konkrete Designansätze
-
Sicherheit: Stärkung der sprachlichen Sicherheit, um die Produktivität der Programmierer und die Korrektheit des Codes zu gewährleisten. Umfangreiche unsichere Sprachen sind schwer zu verwenden
-
Bedienkomfort: Mehr Kontrolle, ohne die Komplexität der Programmierung zu erhöhen, und unter Beibehaltung der Vorteile der Typherleitung
-
Vorhersehbarkeit: Zentrale Performance-Eigenschaften werden auf Ebene des Typsystems explizit sichtbar gemacht, um das Ableiten der Code-Performance zu erleichtern
-
Diese Erweiterungen folgen einem Pay-as-you-go-Ansatz, der nur dort greift, wo er benötigt wird. Das heißt: Wenn die Erweiterungsfunktionen nicht genutzt werden, bleiben die Einfachheit und Muster des bisherigen OCaml unverändert erhalten
-
OxCaml ist mit allen OCaml-Programmen kompatibel und zielt intern auf ein weiterentwickeltes OCaml ab. Dabei bleiben Sicherheit, Benutzerfreundlichkeit und Produktivität des bestehenden OCaml erhalten
Einführung in die Erweiterungsfunktionen von OxCaml
Fearless concurrency
- Um das Problem zu lösen, dass korrekte nebenläufige Programmierung sehr schwierig ist, blockiert OxCaml durch Erweiterungen des Typsystems Datenrennen statisch
Layouts
- Programmierer können das Datenlayout im Speicher explizit festlegen
- Es bietet auch nativen Zugriff auf SIMD-Prozessorerweiterungen moderner Hardware
Allokationskontrolle
- Es bietet Werkzeuge zur feingranularen Steuerung von Speicherallokationen, um den Aufwand der Garbage Collection (GC) zu verringern und Cache-Effizienz sowie Determinismus von Programmen zu verbessern
Quality of life
-
Neben dem System Programming bietet es auch Funktionen, die sich in einzelnen Arbeitsbereichen als hilfreich erwiesen haben
- Polymorphic parameters
- Include functor
- Labeled tuples
- Immutable arrays
Nutzung und Einsatz von OxCaml
-
OxCaml ist als Open Source verfügbar, sodass Forschende, experimentelle Nutzer und Entwickler gleichermaßen durch Tests und Feedback beitragen können
-
Allerdings geben die Erweiterungen von OxCaml keine Zusicherung hinsichtlich Stabilität und Abwärtskompatibilität (mit bestehenden OCaml-Programmen ist Abwärtskompatibilität jedoch gewährleistet)
-
Es werden Versionen bereitgestellt, in denen Standardwerkzeuge von OCaml an OxCaml angepasst wurden
- Paketmanagement: kompatibel mit dune und opam
- Editor-Integration: Unterstützung für LSP-server
- Quellcode-Formatierung und Dokumentationsgenerierung integriert
-
Mehrere von Jane Street veröffentlichte Bibliotheken und Werkzeuge werden in zwei Formen bereitgestellt
- Für Upstream-OCaml: Versionen, aus denen die OxCaml-Erweiterungen entfernt wurden
- Speziell für OxCaml: Versionen, die die Erweiterungsfunktionen nutzen
-
Einige Erweiterungen lassen sich nicht entfernen, daher sind diese Bibliotheken nur in OxCaml nutzbar. Wenn die benötigten Erweiterungen in offizielles OCaml integriert werden, sollen auch OCaml-kompatible Versionen veröffentlicht werden
1 Kommentare
Hacker-News-Kommentare
Ich möchte darauf hinweisen, dass es zu diesem Projekt des Jane-Street-Teams in einer Podcast-Episode mit ihnen eine interessante Diskussion über Performance-Überlegungen beim Arbeiten mit OCaml gab
Die Frage, wie man eine GC-Sprache in einer Umgebung mit extrem niedriger Latenz einsetzt, bleibt weiterhin aktuell
Wenn zum Beispiel mitten im Hochfrequenzhandel eine GC-Pause auftritt, kann das ein ernstes Problem sein
Podcast-Link geteilt
Ich habe tatsächlich auf Twitter direkt Ron Minsky gefragt, warum man für Low-Latency-Anwendungen nicht Rust verwendet
In Rons Antwort wurde zwar anerkannt, dass Rust großartig ist, zugleich lag der Fokus aber auf dem Wert, den gesamten Code in einer Sprache zu halten
Typen, Tools, Bibliotheken und Idiome lassen sich gemeinsam nutzen, und der Wechsel zwischen Projekten wird deutlich einfacher
Außerdem entwickelt sich OCaml intern so weiter, dass die wichtigsten Vorteile von Rust gut integriert werden und sich dadurch schrittweise nutzen lassen
Als Nachteile von Rust wurden lange Compile-Zeiten, ein komplexes Typsystem und Unzufriedenheit mit Async/Await genannt
Vor allem wurde die Haltung betont, ein einzelnes Sprachwerkzeug zu wollen, das für ein breites Spektrum an Aufgaben geeignet ist
Link zum entsprechenden Tweet
Es wurde betont, dass nicht GC-Sprachen an sich das Kernproblem sind, sondern eher die Sichtweise, alle GC-Sprachen über einen Kamm zu scheren
Das wirklich wichtige Problem entsteht dann, wenn eine GC-Sprache keine explizite Manipulation von Stack- und Value-Typen unterstützt
Wenn man die Produktivität einer GC-Sprache mit fein granularen Optionen für systemnahes Coding verbinden möchte, wurden Alternativen wie Cedar, die Oberon-Familie, Modula-3, D, Nim, Eiffel, C#, F#, Swift und Go genannt
Allgemeiner gesprochen kann man in einer Runtime mit GC zur Minimierung von GC-Pausen etwa die parallelen Sammelalgorithmen der JVM nutzen
Allerdings liefert diese Methode keine einheitliche Garantie, sodass zusätzliches Overprovisioning beim System-RAM nötig sein kann
Darüber hinaus kann man Server absichtlich überprovisionieren, damit einzelne Server kurzzeitig aus dem Pool genommen werden können, um „Offline-GC“ durchzuführen
Solche Ansätze erfordern Zusammenarbeit zwischen Request-Router und Servern und sind daher nur dann sinnvoll, wenn genug Budget für horizontale Skalierung vorhanden ist
Erklärung zu JVM Parallel GC
Es wurde von Erfahrungen berichtet, bei denen mehrere Systeme unter GC-Compaction-Problemen litten
In Trading-Systemen gibt es nach dem Start typischerweise die Regel, Allokationen so weit wie möglich zu minimieren
Für JS gibt es eine Bibliothek namens "Zero", die Utilities ohne Allokationen bereitstellt
Ich habe den Link nicht geprüft, aber in einer Umgebung mit Handelsbeginn und Handelsschluss, wie beim Trading, könnte man den GC während der Handelszeit vielleicht deaktivieren und nach Börsenschluss neu starten
Ich möchte betonen, dass das erste aus diesem Fork in den Upstream übernommene Feature labeled tuples sind
Unterstützung ist für OCaml 5.4 geplant
Upstream-PR-Link
Link zur zugehörigen Diskussion
Auch wenn dieses Feature etwas klein wirkt, ist die Vorfreude darauf ziemlich groß
Ich möchte ergänzend das Paper und den Vortrag des Autors zu diesem Feature auf der ML2024 erwähnen
Youtube-Video
PDF des Papers
Ein Beispiel für labeled tuples ist die Vermeidung von Fehlern bei der Reihenfolge eines Paars; persönlich gefallen mir aber anonyme Records in F# besser
Zum Beispiel gibt es bei
{| product = 6; sum = 5 |}keine Fehler durch Feldreihenfolge, weil die Reihenfolge keine Bedeutung hatIn diesem Fork wurden auch immutable arrays in 5.4 übernommen, nur mit leicht abweichender Syntax
Es wurde betont, dass anonyme labeled structs und enums zu den am meisten gewünschten Features in Programmiersprachen gehören
Als Beispiel wurde genannt, dass man in Rust sowohl labeled als auch unlabeled structs definieren kann
Es wurde aber bedauert, dass sich kein anonymer labeled struct als Funktionsrückgabetyp verwenden lässt
Mir war nicht klar, dass dieser Fork SIMD unterstützt
Wenn unboxed types, explizite Stack-Allokation und sogar Windows-Unterstützung dazukommen, könnte OxCaml meiner Meinung nach statt F# in Consumer-Bereichen wie Game Dev durchaus attraktiv werden
Windows-Support ist nicht grundsätzlich blockiert, erfordert aber etwas Arbeit
Ich möchte besonders hervorheben, dass OxCaml SIMD-Support hinzugefügt hat
Für diejenigen, die einen neuen opam switch verwenden, hier ein Tipp zur Konfiguration von Umgebungsvariablen
env OCAMLPARAM="alert=-unsafe_multidomain,_," opam install cohttp-lwt-unixDamit lässt sich das Problem lösen, dass Installationen bestehender Pakete unnötig scheitern, wenn Warnungen (alerts) zu Fehlern hochgestuft werden
Durch das Deaktivieren dieses alerts über die Umgebungsvariable
OCAMLPARAMlassen sich Installationsprobleme vermeidenIch bin an das hervorragende vscode-Plugin für Golang gewöhnt und frage mich, ob für das OCaml-Ökosystem ebenfalls eine Integration mit vscode geplant ist
Die Integration mit vscode hat das Setup sehr einfach gemacht
Wenn OxCaml an Popularität gewinnt, ist weiterer Integrationsfortschritt natürlich gut möglich
Ich selbst nutze emacs, daher kann ich es nicht im Detail sagen, aber es wirkt wie eine natürliche Entwicklung
Ich möchte eine Micro-Size-Version von OCaML erwähnen
Link zum mlite-Projekt
Es wurde gefragt, ob der Zweck der Veröffentlichung dieses Projekts vielleicht darin besteht, dass LLMs die Informationen indexieren und für offene Modelle nutzen können
Selbst bei normalem OCaml sind LLMs viel zu schwach und die Datenmenge ist gering; bei OxCaml gibt es noch weniger Material, deshalb ist das meiner Einschätzung nach überhaupt nicht der Grund
Für einen solchen Zweck wäre es sinnvoller, ein eigenes Dokumentations-MCP zu bauen
Der Signalwert ist nicht hoch genug, daher hat das praktisch keine Bedeutung
Selbst beim Vervollständigen von Gleam ist die Leistung von LLMs sehr schwach; sie scheitern sogar dann, wenn man klare Muster und Hinweise zu typischen Fehlern vorgibt
Deshalb ist das Signal zu schwach, um die Bereitstellung von OxCaml-Informationen als Ziel plausibel erscheinen zu lassen
Es ist ein interessanter Beobachtungspunkt, dass OxCaml eine Erweiterung eines Dialekts einer ML-Familiensprache ist
Ich bin gespannt, wie der nächste Schritt aussehen wird
Ich habe mich schon gefragt, wer problematischer ist: die Leute, die ständig Features an bestehende Sprachen anbauen, oder diejenigen, die gleich ganz neue Sprachen erschaffen
Ich gehöre eher zur zweiten Gruppe, aber ich denke, Programmierer haben eine genetische Eigenschaft, Werkzeuge nicht einfach so zu lassen, wie sie sind
Halb im Scherz kam die Aufforderung, ob man vielleicht auch F# vorstellen könnte
Es wurde klargestellt, dass der Name "oxidized" bei diesem Projekt mit den angestrebten Features von Rust zusammenhängt, etwa fearless concurrency und dem Vermeiden von GC, nicht aber damit, dass tatsächlich Rust verwendet wird
Es wurde angemerkt, dass die Benennung etwas verwirrend sein kann
Tatsächlich kommt der Name Rust ironischerweise nicht von Rost, sondern vom Schimmelpilz „Rust“
Es wurde geteilt, dass Jane Street seit Langem eine Blogserie mit dem Titel 'Oxidizing OCaml' betreibt
Der Begriff wurde auch im Titel des Papers „Oxidizing OCaml with Modal Memory Management“ verwendet, ohne dass das Wort 'oxidize' im Paper selbst klar definiert oder zitiert würde
Irgendwie seltsam, aber zugleich ein ziemlich eingängiger Name
Es wurde prognostiziert, dass Rust praktischer bleiben wird, solange dieses Projekt keine Feature-Parität mit Rust bei der Integration eines benutzerdefinierten Tracing-GC erreicht, mit dem sich allgemeine Graphstrukturen handhaben und zugleich maximale Performance anstreben lassen
Andernfalls wirkt es eher so, als würde es nur weitergeführt, weil bereits viel OxCaml-bezogener Code vorhanden ist