2 Punkte von GN⁺ 2023-08-20 | 1 Kommentare | Auf WhatsApp teilen
  • WebAssembly wird für Cloud- und Edge-Computing immer wichtiger, und Moonbit zielt als Wasm-first-Sprache darauf ab, die Effizienz, Sicherheit und geringe Größe von Wasm leichter nutzbar zu machen
  • Moonbit adressiert die Grenzen von Rust und C/C++, deren Lernkurve und lange Kompilierzeiten belastend sind, sowie von Go, dessen erzeugter Code groß und ineffizient ist
  • Der Schwerpunkt des Designs liegt auf schnellem Build und schneller Ausführung, kleiner Wasm-Ausgabe und einfacher Nutzbarkeit; dazu gehören Optimierungen mit mehreren Intermediate Representations, parallele semantische Analyse auf Funktionsebene und inkrementelle Reanalyse
  • Am Fibonacci-Beispiel werden lokale Typinferenz, die kleinste Wasm-Ausgabe, höhere Geschwindigkeit als Go bei ähnlicher Performance wie Rust sowie die Unterstützung rekursiver Closures und von exhaustive pattern match hervorgehoben
  • Derzeit werden eine Online-IDE, CLI-Tools, Dokumentation und eine VSCode-Erweiterung angeboten; angestrebt werden beta status bis Ende des 2. Quartals 2024 und die Veröffentlichung des Source Codes nach Erreichen von Beta-Qualität

Ziel: eine WebAssembly-orientierte Sprache

  • WebAssembly ist eine plattformübergreifende Befehlssatzarchitektur und gewinnt wegen ihrer Effizienz, Sicherheit, geringen Größe und ihres offenen Standards in Cloud- und Edge-Computing an Bedeutung
  • Bestehende Optionen schöpfen das Potenzial von Wasm aus dieser Sicht nicht vollständig aus
    • Low-Level-Wasm-Sprachen wie Rust und C/C++ sind schwer zu erlernen, und lange Kompilierzeiten können die Entwicklung verlangsamen
    • High-Level-Sprachen wie Go erzeugen aus dieser Sicht ineffizienten und großen Code, sodass sich die Vorteile von Wasm bei Geschwindigkeit und kleiner Größe nur schwer ausspielen lassen
  • Moonbit versteht sich als Wasm-first-Sprache, die schnell baut und ausführt, kleine Wasm-Ausgaben erzeugt und so leicht zu lernen sein soll wie Go

Sprachdesign und Team

  • Moonbit wird von Hongbo Zhang und einem Team mit mehr als zehn Jahren Erfahrung in Sprachdesign und -entwicklung geführt
  • Zhang hat zu OCaml, ReScript und Flow beigetragen und war beim ReScript-Toolchain für den schnellen Compiler, die Standardbibliothek und das Build-System als chief architect verantwortlich
  • Das Sprachdesign ist sowohl von Go als auch von Rust beeinflusst
    • Es übernimmt die Einfachheit von Go, insbesondere das Paketsystem
    • Es übernimmt die Ausdrucksstärke von Rust, darunter Pattern Matching, Typinferenz, Generics und trait-ähnlichen ad-hoc-Polymorphismus
  • Das fehlertolerante Typsystem wurde mit Blick auf Geschwindigkeit, Parallelisierbarkeit und inkrementelle Prüfungen entworfen; IDE-Support ist ein zentrales Ziel

Schnelle Builds und schnelle Ausführung

  • Moonbit zielt auf eine durchgängig schnelle Sprache ab, die sowohl Entwicklungs- als auch Laufzeitperformance umfasst
  • Für die Optimierung des gesamten Programms werden mehrstufige Intermediate Representations (IR) verwendet
    • Die Speicheranordnung wird verbessert, um Cache Misses zu verringern
    • Das bietet besseren Kontext für Datenfluss- und Kontrollflussanalysen
    • Im Vergleich zu den meisten bestehenden Strukturen für Link-Time Optimization soll die Programmstruktur umfassender verstanden werden, was effektivere Optimierungen ermöglicht
    • Redundanzen auf höherer Ebene, die auf niedriger Ebene nicht sichtbar sind, können erkannt und entfernt werden
  • Für schnelle Build-Performance, die für IDE-Funktionen wichtig ist, erlaubt Moonbit parallele semantische Analyse auf Funktionsebene
    • Anders als bei ReScript und Rust ist parallele semantische Analyse auf Funktionsebene möglich
    • Auf derselben Granularität wird inkrementelle Reanalyse durchgeführt, wodurch sich große Monorepos handhaben und Reaktionszeiten im Millisekundenbereich erreichen lassen sollen

Kleine Wasm-Ausgabe

  • Moonbit wurde mit Blick auf effektive dead code elimination entworfen
  • Sprachfeatures, die diese Analyse behindern, wurden ausgeschlossen, und auch die Standardbibliothek ist so aufgebaut, dass sich toter Code leicht entfernen lässt
  • Durch Optimierung des gesamten Programms soll die endgültige Codegröße stark reduziert werden
    • Eine kleinere Codegröße soll die Sicherheit erhöhen und die Angriffsfläche verringern
    • In serverlosen Computing-Umgebungen soll das einen schnellen Start sicherstellen

Funktionen und Tools für bessere Nutzbarkeit

  • Moonbit bietet automatische Speicherverwaltung und unterscheidet sich damit von Rust
  • Anders als Go sollen riskante Elemente wie Pointer oder left value vermieden werden
  • Für datenorientierte Programmierung bietet es sichere Funktionen
    • algebraic data types
    • ad-hoc polymorphisms
    • pattern match
  • Über die Sprache hinaus will Moonbit auch als Plattform dienen und bietet schon in der frühen Phase ein Toolset
    • schnelles Build-Tool
    • Paketmanager
    • Compiler
    • IDE
    • containerlose Cloud-IDE, auf die sich mit nichts außer einem Browser von überall zugreifen lässt
    • Diese Cloud-IDE bietet auch Offline-Funktionen und soll sich damit von bestehenden Cloud-IDEs unterscheiden

Unterschiede am Fibonacci-Beispiel

  • Im Fibonacci-Beispiel wird die Implementierung der Funktion fib in MoonBit, Go und Rust verglichen
  • Laut Benchmark zeigt MoonBit Unterschiede bei Typinferenz, Codegröße, Performance und Nutzbarkeit
    • Lokale Typinferenz: MoonBit leitet den Typ der lokalen Funktion aux ab
    • Kleine Wasm-Größe: MoonBit erzeugt die kleinste Wasm-Ausgabe
    • Performance: schneller als Go und ähnlich wie Rust
    • Nutzbarkeit: unterstützt wie Go rekursive Closures, deren Umsetzung in Rust als sehr schwierig beschrieben wird
    • Unterstützt wie Rust exhaustive pattern match und sei deutlich mächtiger als Go-switch-case

Aktueller Stand und Roadmap

  • Moonbit ist ein sich schnell veränderndes Projekt, bietet aber bereits Einstiegspunkte
  • Die Entwicklung von Sprach-Toolchains dauerte früher mehrere Jahre bis zu einem Jahrzehnt, doch durch gesammelte Erfahrung und ein von Anfang an aufgebautes dediziertes Team sei die Entwicklung vereinfacht worden
  • Bis Ende des 2. Quartals 2024 wird das Erreichen von beta status erwartet
    • beta status bedeutet relative Stabilität, wenige Bugs und eine robuste FFI für die Interaktion mit Wasm-Hosts
  • Der Source Code soll nach Erreichen von Beta-Qualität veröffentlicht werden
  • Zu den strategischen Plänen gehören die Integration von Wasm GC für Wasm 2.0 und ein eigener GC für Wasm 1.0; dies soll mit den Wasm-Proposals abgestimmt sein

Community-Kanäle

1 Kommentare

 
GN⁺ 2023-08-20
Meinungen auf Hacker News
  • Ich bin der Lead dieses Projekts. Man kann es jetzt direkt in der Online-IDE https://try.moonbitlang.com ausprobieren und mit F5 ausführen.
    Die Dokumentation findet sich unter https://github.com/moonbitlang/moonbit-docs; der Compiler soll veröffentlicht werden, sobald er den Beta-Status erreicht. Erwartet wird das Ende des 2. Quartals 2024.

    • Das sind die Fragen, die ich mir zuerst stelle, wenn ich eine neue Programmiersprache sehe: Wie schreibt man asynchronen Code? Gibt es weniger Mainstream-artige Features wie algebraische Effekte (algebraic effects), Kontexte/Capabilities (contexts/capabilities) oder lineare Typen (linear types)? Ist das Typsystem sound, und sind Type Casts nötig? Werden Interfaces/Traits/Protokolle unterstützt? Wie mächtig sind Generics?
      Zum Beispiel würde ich gern prüfen, ob es explizite Varianzannotationen für Typparameter, Lower-/Upper-Bound-Constraints, Higher-Kinded Types gibt, ob strukturelle oder nominale Subtypen im Mittelpunkt stehen und ob algebraische Datentypen sowie generalisierte algebraische Datentypen vorhanden sind.
      Referenzen: https://v2.ocaml.org/manual/effects.html, https://docs.hhvm.com/hack/contexts-and-capabilities/introdu..., https://austral-lang.org/linear-types
    • Viele dürften sich für Lizenz, Preis und Kontrolle über das Projekt interessieren. Das jetzt offenzulegen könnte der kommerziellen Strategie zwar schaden, aber Geheimniskrämerei und Unsicherheit können das Interesse abkühlen lassen.
    • Die Dokumentation unter https://moonbitlang.com/docs/syntax/ ist wegen Text- und Hintergrundfarbe schwer zu lesen.
    • Ich frage mich, ob ein eigenes fn-Keyword wirklich nötig ist. Ich sehe nicht, worin der grundlegende Unterschied zwischen func und fn besteht.
    • Ich frage mich, ob man wirklich zwischen func und fn unterscheiden muss und ob der ->-Pfeil für den Rückgabewert in Funktionssignaturen nötig ist.
      Die Syntax für neue Typen lautet struct User; hier fände ich wie in Go type User struct besser. Dann ließen sich auch Funktionstypen für fn-Variablen wie type AssignUser func(name: String, id: Int) -> Int definieren.
      Außerdem frage ich mich, ob : dem Lexer oder Parser hilft. Könnte man in Funktionssignaturen statt func(name: String) nicht func(name String) schreiben, und könnten Typdeklarationen nicht mut elems List[int] statt mut elems: List[Int] sein? Das ist kleinliche Kritik, aber insgesamt gefällt es mir.
  • Die Seite vergleicht mit Rust und Go, aber mir scheint ein Vergleich mit AssemblyScript passender. AssemblyScript ist ebenfalls WASM-nativ, und auch dort ist das Ökosystem noch klein.
    Im Unterschied zu Moonbit ist es allerdings für Leute vertraut, die schon TypeScript verwendet haben; daher frage ich mich, warum man Moonbit statt AssemblyScript verwenden sollte.

    • Weil Moonbit eine moderne Sprache ist, während AssemblyScript Fehler der Vergangenheit mitschleppt. Moonbit unterstützt zum Beispiel Pattern Matching, und die meisten Sprachkonstrukte sind Expressions.
      AssemblyScript hat kein Pattern Matching und besteht hauptsächlich aus Statements. Moonbit hat algebraische Datentypen; ob AssemblyScript so etwas hat, weiß ich nicht genau. Es könnte auch weitere Unterschiede bei der Runtime geben, aber anhand der Website ist das schwer zu beurteilen.
    • Es scheint Grain viel näher zu sein als AssemblyScript: https://grain-lang.org/
    • Der Vergleich mit Rust und Go liegt wohl daran, dass beide populäre Sprachen sind und WASM-Support erster Klasse haben, aber ich stimme zu, dass man es mit AssemblyScript vergleichen sollte.
  • Für Top-Level-Funktionsdefinitionen func und für verschachtelte Funktionsdefinitionen fn als Keyword zu verwenden, ist keine gute Idee. Unabhängig vom jeweiligen Kontext sollte man sich auf eines von beiden festlegen.

    • Das könnte daran liegen, dass verschachtelte Funktionen Closures sind. Anders als bei Top-Level-Deklarationen kann man Namen und Typ weglassen und Werte capturen; Sprachen mit eigener Closure-/Lambda-Syntax sind nicht selten.
      Ob das wirklich nötig oder ein gutes Design ist, ist eine andere Frage, aber es gibt viele Präzedenzfälle.
    • Ich halte das für ein elegantes Design, weil es für verschachtelte Funktionen kürzere und besser lesbare Funktionsdefinitionen erlaubt. fn ermöglicht es, Namen und Typ wegzulassen, und das kürzere Keyword zeigt auch, dass die Funktionsdefinition kürzer werden kann.
  • Ich bin gespannt, dass eine moderne Garbage-Collection-Sprache mit WASM als Ziel erscheint. Der nächstliegende Vergleich dürfte wohl Grain sein: https://grain-lang.org/

    • Der Grain-Compiler soll nicht in reinem OCaml, sondern in ReasonML geschrieben sein. Es wirkt ein wenig komisch, wie sich solche Nischentechnologien ohne Scheu übereinanderstapeln.
  • „Die Entwicklung einer kompletten Sprach-Toolchain dauerte früher mehrere Jahre bis hin zu einem Jahrzehnt, wurde aber dank gesammelter Erfahrung und eines von Anfang an für Moonbit zusammengestellten, dedizierten Spitzenteams vereinfacht. Wir erwarten, dass Moonbit bis Ende des 2. Quartals 2024 den Beta-Status erreicht; das bedeutet einen relativ stabilen Stand mit wenigen Bugs und einer robusten FFI für die Interaktion mit Wasm-Hosts. Sobald wir Beta-Qualität erreicht haben, werden wir den Quellcode veröffentlichen. Strategisch planen wir, entsprechend den Wasm-Proposals für Wasm 2.0 Wasm GC zu integrieren und für Wasm 1.0 einen eigenen GC bereitzustellen“, heißt es dort.
    Deshalb ist https://github.com/moonbitlang/ derzeit leer.

  • Wenn man sich die Kommentare hier ansieht, scheint Moonbit Garbage Collection zu haben. Wenn das resultierende Fibonacci-Binary aber 253 Byte groß ist, ist vermutlich kein GC enthalten.
    Ich frage mich, ob es den vorgeschlagenen nativen WASM-GC nutzt oder ob das Build-System klug genug ist zu erkennen, dass hier kein GC nötig ist, und ihn deshalb herauslässt.

    • Wenn man mit der rechten Maustaste auf die Datei klickt und den vorletzten Menüpunkt Compile to Wat auswählt, kann man den WASM-Text direkt ansehen.
      In der Ausgabe des Fibonacci-Beispiels sieht man nur den Import print_i32, Speicher- und Funktionsdefinitionen sowie den Export _start; es sieht nicht so aus, als wäre eine GC-Runtime angehängt.
    • Vermutlich wird sie intelligent weggelassen. Codegröße ist schließlich eines ihrer Ziele.
  • Das erinnert an Grain. Da es eine weitere Wasm-first-Programmiersprache ist, wäre es wohl sinnvoll, Grain als Vergleich hinzuzunehmen.
    https://grain-lang.org/

  • Der Link „About Team“ führt auf eine chinesische edu.cn-Seite. Es wirkt wie ein Universitätsprojekt, aber sicher bin ich mir nicht. Die Seite „Join Us“ ist ebenfalls auf Chinesisch, und das Beispiel auf der Homepage sieht so aus, als bräuchte es JavaScript von baidu.com.

    • Auch mit aktiviertem umatrix-Plugin funktioniert die Demo weiterhin. Die benötigten Skripte kommen von unpkg und msecnd (einer Microsoft-Domain); baidu ist nicht nötig.
  • In Go würde man Fibonacci nicht so implementieren.

    • Ich mag Go nicht besonders, aber man muss anerkennen, dass dieser Benchmark keinen Sinn ergibt. Wenn man in einer Sprache, die keine Tail-Call-Optimierung unterstützt, Tail Calls verwendet, ist es selbstverständlich, dass das Ergebnis schlecht ausfällt.
      Es scheint einfacher gewesen zu sein, ein paar Zahlen hinzulegen, statt idiomatische Implementierungen miteinander zu vergleichen und die Trade-offs differenziert zu diskutieren. Selbst wenn es nur ein einfacher Teaser für die Sprache ist, wäre ein Hinweis zu TCO gut, damit Leute nicht in die Irre geführt werden.
    • Ein konstruiertes Beispiel mit WASM und Go zu verwenden und dabei TinyGo nicht zu erwähnen, wirkt nicht besonders ehrlich.
    • Auch in Rust würde man es nicht so implementieren. Das ist ein ziemlich schlechter Benchmark. Meiner Erfahrung nach dürften die fehlende Tail Recursion und die switch-Anweisung die Ursache sein, und in Go kann das langsam sein.
      Als Teaser für Moonbit ist es trotzdem in Ordnung.
  • Ich frage mich, ob dieses Projekt etwas mit Meta zu tun hat. Der Entwickler Hongbo Zhang hat bei Meta an Open-Source-Programmiersprachenprojekten wie ReasonML und Flow gearbeitet und ist laut LinkedIn immer noch bei Meta beschäftigt.