2 Punkte von GN⁺ 2023-08-02 | 1 Kommentare | Auf WhatsApp teilen
  • ORC-Speicherverwaltung ist jetzt der Standard
  • Das JavaScript-Backend verwendet für int64 und uint64 standardmäßig **BigInt`; wenn diese Typen in Code verwendet werden, der mit dem JS-Backend zusammenarbeitet, können Anpassungen nötig sein
  • --experimental:strictEffects ist jetzt immer aktiviert, und Callback-Parameter benötigen eine effectsOf-Annotation
  • Die Standard-Markup-Sprache für Dokumentationskommentare wechselt vom bisherigen Modus RstMarkdown zu Markdown; außerdem kommen das Pragma {.doctype: Markdown | RST | RstMarkdown.} sowie die Befehle md2html und rst2html hinzu
  • Ein Teil der os-bezogenen Funktionen der Standardbibliothek wurde in eine neue Schnittstelle ausgelagert, die die Path-Abstraktion verwendet, und wird über die Module std/oserrors, std/envvars, std/paths, std/dirs, std/files, std/symlinks, std/appdirs, std/cmdline bereitgestellt
  • Mehrere Module der Standardbibliothek wurden in Nimble-Pakete verschoben; für die Verwendung von std/punycode, std/asyncftpclient, std/smtp, std/db_*, std/md5, std/sha1, std/sums ist nun eine Installation per nimble oder atlas erforderlich
  • Die Verwendung eines namenlosen break innerhalb eines namenlosen block wird als veraltet eingestuft und soll in einer zukünftigen Version zu einem Fehler werden
  • Die Definition von "strictFuncs" wurde geändert, sodass Schreibzugriffe auf Dereferenzierungen von ref oder ptr verboten sind
  • Das Tuple-Unpacking von Variablen wird als syntaktischer Zucker behandelt, der zu mehreren Zuweisungen expandiert; dadurch ist auch verschachteltes Tuple-Unpacking möglich
  • Top-down-Inferenz wurde an mehreren Standardstellen implementiert, sodass der Beispielcode zur Initialisierung von seq[(float, byte, cstring)] kompiliert
  • Für Objektfelder können Standardwerte festgelegt werden; diese werden für Felder verwendet, die nicht explizit initialisiert wurden
  • Der experimentelle Schalter strictDefs wurde hinzugefügt; er prüft, ob Variablen vor ihrer Verwendung explizit einen Wert zugewiesen bekommen haben, und ob let-Variablen genau einmal zugewiesen wurden
  • Für die C++-Interoperabilität wurden das Pragma virtual und ein erweitertes Pragma constructor hinzugefügt, sodass Konstruktoren und virtuelle proc-Definitionen möglich sind, die auf C++-Konstruktoren und virtuelle Methoden abgebildet werden
  • Nimble 0.14 wird mitgeliefert, unterstützt Lockfiles, und der Speicherort der Bibliotheken wechselt von $nimbleDir/pkgs zu $nimbleDir/pkgs2

1 Kommentare

 
GN⁺ 2023-08-02
Meinungen auf Hacker News
  • Ich setze Nim zufrieden in der Produktion ein. Hauptsächlich entwickle ich Tools für Datenanalyse und Berichtserstellung und kompiliere sie zu CLI-Executables, die von Server-Skripten aufgerufen werden.
    Nim erzeugt schnelle und kleine Executables und bietet gute Libraries für heterogene JSON-Datenstrukturen und Dataframes. Es bevorzugt den Stack stark: Selbst dynamische Datenstrukturen wie Sequenzen und Tabellen bestehen aus Pointern auf dem Stack, die auf Heap-Daten zeigen, wobei die Lebensdauer vom Stack-Frame verwaltet wird.
    Im Programm gibt es kaum dynamische Referenzen, und man muss sich keine Gedanken über GC machen. Das Typsystem ist einfach und vernünftig und führt leicht zu korrektem Code. Auch die Defaults liegen nahe an referenzieller Transparenz; solange man nicht explizit davon abweicht, ist alles immutable und wird als Wert übergeben.
    Generics sind mächtig und verhalten sich erwartungsgemäß, und die Uniform Function Call Syntax ist absurd nützlich. Wenn man nur Prozeduren und Funktionen schreibt, die einen bestimmten Typ als erstes Argument nehmen, kann man das Äquivalent von Methoden oder Interfaces schreiben; dadurch braucht man solche Abstraktionen nicht mehr, und die Codestruktur bleibt einfach und flach.
    Es macht so viel Spaß, dass es mich daran erinnert, als ich damals D entdeckte – nur ist es eher noch besser. Wenn man sich ein nativ kompiliertes Python mit Typannotationen vorstellt, das fast zu 100 % aus Business-Logik besteht und keinen Ballast hat, kommt das der Nim-Erfahrung nahe.

    • Ist diese Beschreibung nicht im Grunde so etwas wie ein C++ vector oder map auf dem Stack? Intern wird bei Bedarf alloziert, und wenn der gesamte Container den Scope verlässt, wird er zerstört.
    • Das macht Lust, mir Nim einmal anzusehen. Ich frage mich, wie das Build-System ist. CMake ist wirklich schmerzhaft.
    • Es sieht wirklich wie Python aus. Ich hoffe, es wird populärer; es wirkt wie ein deutlich leichter zu verwendendes Rust.
    • Sieht gut aus. Ich frage mich, in welchem Zustand das Package-Management ist und wie robust das aktuelle Ökosystem ist.
  • Ich freue mich darauf, diese Version auszuprobieren. Aus der Perspektive von 25 Jahren professioneller Programmierung sehe ich Nim als eine Sprache, die die Stärken mehrerer Welten gut vereint.
    Sie ist so einfach zu benutzen wie Python, stark typisiert, aber mit hervorragender Typinferenz, und die Defaults sind schnell und sicher. Sie passt gut für alles von Embedded bis High-Performance Computing.
    Dank UFCS, Generics und Concepts bekommt man die Vorteile von OOP, muss aber weniger Gerüstcode schreiben, der zur Organisation endlose fragile Datenbeziehungen aufbaut. Anders als in Python werden Mehrdeutigkeiten zu Compile-Fehlern.
    Ich habe das Gefühl, dass dasselbe Programm viel kleiner, lesbarer und leichter verständlich ist als in den meisten anderen Sprachen. Hinter den Kulissen passiert auch nicht allzu viel Magie, weil die Defaults sinnvoll sind.
    Compile-Time-Metaprogramming ist auf einem anderen Niveau. Es ist ohne separaten Dialekt oder Ersetzungstricks als Kern der Sprachgestaltung integriert und intuitiv zu verwenden. Zum Beispiel lässt sich aus Dateien leicht maßgeschneiderter Parsing-Code generieren, um repetitives Boilerplate zu entfernen, und das Kompilieren ist schnell.
    Dank des hervorragenden Typsystems ist es einfacher, guten Code zu schreiben als in Python, während die Performance an C/C++ heranreicht; außerdem ist die Auslieferung als kleine, eigenständige Executables sehr einfach.
    Dazu kommen native ABIs für C, C++, ObjC und JS, ein hervorragendes FFI und gute Python-Interoperabilität. Man kann bestehende Ökosysteme direkt nutzen, ohne sie neu schreiben zu müssen.
    Man kann sich vorstellen, Python-artigen Pseudocode für den ESP32 zu schreiben, der ohne großen Aufwand sehr effizient ist und bei Bedarf auch Bare-Metal-Kontrolle erlaubt. Oder Web-Apps mit Backend und Frontend in derselben effizienten Sprache zu schreiben, schnelle Bullet-Hell-Spiele zu bauen und sich dennoch nicht um GC sorgen zu müssen, weil standardmäßig auf dem Stack alloziert wird, sofern man nichts anderes angibt.
    Auch aus Business-Sicht ist es sehr wertvoll, dass man wie mit Python schnell Prototypen bauen kann, die bereits schnell und leichtgewichtig genug für die Produktion sind. Es kann zur Geheimwaffe eines Unternehmens werden.

    • Ich verwende Nim als Scripting-Target für Spiele und andere Zwecke, über die ich nicht im Detail sprechen kann, weil es nach C und C++ übersetzen kann.
      Es ist wirklich großartig, die darunterliegende C-Runtime-Umgebung direkt verwalten zu können und darüber eine moderne High-Level-Sprache zu nutzen, in der Dinge wie JSON erstklassig unterstützt werden. Selbst als jemand, der Python mag, finde ich Nim besser – ein besseres Python.
    • Mich würde interessieren, wie das konkret funktioniert, Web-Apps mit Backend und Frontend in derselben effizienten Sprache zu schreiben.
      Insbesondere möchte ich wissen, wie bequem die JS-Interoperabilität während der Entwicklung ist und ob sie über das Kompilieren von Nim zu einer eigenständigen JS-Library hinausgeht. Kann man Browser-APIs direkt aus Nim aufrufen oder über ziemlich einfache Wrapper?
    • In Fällen, in denen Mikrosekunden zählen, etwa bei Code zur Verarbeitung eines 22-kSPS-ADC auf dem ESP32, waren ehrlich gesagt etwa 2 Stunden Tuning nötig. Damals lernte ich Nim gerade erst, und es ging vor allem darum, zusätzliche Allokationen zu vermeiden.
      Trotzdem gab es über ungefähr vier Jahre hinweg keine großen Performance-Regressionen und keine notwendigen Änderungen.
  • Glückwunsch an alle Beteiligten und an die gesamte Nim-Community. Ich verwende Nim seit zehn Jahren als Hauptsprache, und die neuen Features von Nim 2.0 gefallen mir sehr.
    Einige davon sind für meine Projekte echte Gamechanger. Objekt-Defaults könnten Norm[1] theoretisch ermöglichen, nicht nur mit Objektinstanzen, sondern auch mit Objekttypen zu arbeiten. Ohne die neu hinzugekommenen überladbaren Enums wäre Karkas[2] überhaupt nicht möglich gewesen. Es ist allerdings noch in Arbeit.
    [1] https://norm.nim.town
    [2] https://karkas.nim.town

    • Von den jüngsten Änderungen gefallen mir die Defaults am besten. Sie sind allgemein nützlich und reduzieren nicht nur Initialisierungs-Boilerplate weiter, sondern ermöglichen auch, bei Dingen wie Enums zur Compile-Zeit gültige Zustände zu garantieren. Vermutlich gilt das auch für Objektvarianten.
  • Nim ist eine wirklich gute Sprache zum Schreiben von Software. Man kann schnell ausliefern, mit Freude entwickeln und trotzdem sehr performante Software bauen.
    Allerdings gibt es meiner Erfahrung nach noch einige scharfe Kanten. Man muss C/C++-Compiler und Optionen aufeinander abstimmen, Fehlermeldungen sind sehr dürftig, und manche Libraries funktionieren nur mit bestimmten Einstellungen und Systemen. Angesichts der kleinen Community ist das aber schwer stark zu kritisieren. Die VS-Code-Integration funktionierte gut und stürzte kaum ab.

    • Schlechte Fehlermeldungen und unzureichendes Tooling sind meiner Meinung nach die größten Probleme von Nim. Ansonsten ist es insgesamt eine hervorragende Sprache.
    • Zumindest das Error Reporting wurde kürzlich verbessert: https://nim-lang.org/blog/2023/03/31/version-20-rc2.html
  • Wenn Manning Publications das hier sieht, wäre es schön, wenn ein Buch zur neuesten Nim-Version erscheinen würde – und wenn sie ein anderes Layout mit besser lesbarer Schrift in Betracht ziehen würden.
    Ich habe das hervorragende Buch von Dominik Picheta gekauft, musste aber das PDF verwenden, weil die gedruckte Ausgabe wegen der dünnen Schrift selbst mit angepasster Brille zu schwer zu lesen war. Schriftbestandteile wie Striche und Stämme sind viel zu dünn.
    Ich fragte mich, ob das wegen meines Alters mein Problem sei, und verglich es mit dem Original der 2. Auflage von K&R – das war immer noch perfekt lesbar.

  • Reddit hat darüber geschrieben, wie sie Nim verwenden: https://www.reddit.com/r/RedditEng/comments/yvbt4h/why_i_enj...
    Immer mehr große Unternehmen und Startups setzen Nim ein. Ich freue mich sehr auf Nim 2.0 und bin allen Mitwirkenden sehr dankbar.

    • Dass immer mehr große Unternehmen und Startups es einsetzen, ist interessant. Ich frage mich, ob es dazu Statistiken oder Daten gibt oder ob das eher anekdotisch ist.
      Falls es anekdotisch ist: Kannst du ein paar Firmennamen nennen?
  • Nim war eine ganze Weile meine Lieblingssprache, und ich freue mich sehr, dass 2.0 endlich erschienen ist. Viele der Features in dieser Version wurden lange erwartet.
    Der einzige Nachteil ist, wie ganz unten erwähnt, dass einige mitgelieferte Module in Third-Party-Repositories verschoben wurden. Kein großes Problem, aber es war schön, SQLite-Support direkt in der Library zu haben. Wenn man anfängt, einige Datenbanken zu unterstützen, entsteht natürlich Druck, noch mehr Datenbanken zu unterstützen. Dass aber sogar der Support für MD5 und SHA1 herausgenommen wurde, überrascht mich etwas.

    • Sobald etwas in einer „Batteries included“-Library landet, neigt die Library dazu, zu stagnieren. Python schleppt seit den 90ern einige tote Batterien mit, aber dort ist das nötig.
      Pfad- oder Logging-Support ist im Standard gut aufgehoben, aber manche Dinge sollten Third-Party bleiben, damit sie sich besser weiterentwickeln können.
  • Glückwunsch an alle Beteiligten. Nim fühlt sich wirklich wie eine interessante Sprache an.
    Ich versuche, einen Grund zu finden, sie bei der Arbeit einzusetzen. Mein Arbeitsbereich liegt im Umfeld von Mobile; attraktiv ist, dass man nach JS und ObjC kompilieren kann, aber bisher bin ich nicht über ein wenig Herumprobieren hinausgekommen. Im Vergleich zu Rust ist der Einstieg deutlich einfacher.

    • In gewisser Weise passend dazu: Mit Denim kann man Nim-Code aus Node.js/Bun heraus aufrufen: https://github.com/openpeeps/denim
      Es funktioniert über das Erstellen von Node-Addons. Gut geeignet, um Nim-Code in Web-Apps wiederzuverwenden oder für performancekritischen Code.
  • Ich habe mir Nim vor ein paar Monaten angesehen, und vom Funktionsumfang her hatte es vieles, was ich mir in Python wünschen würde: einfache Interoperabilität mit C/C++, statische Typen, Kompilierung sowie die Möglichkeit, für Android/iOS cross-zu-kompilieren und dort auszuführen.
    Aber obwohl die Sprache nicht neu ist, ist das Ökosystem klein. Es gibt nicht viele hochwertige Libraries wie Pythons numpy, scipy, pandas oder opencv. Schade, dass kein großer Player darauf setzt; es wäre schön gewesen, wenn Unreal Engine Nim übernommen hätte, statt mit Verse eine eigene neue Skriptsprache zu bauen.
    Ein weiterer Nachteil ist die fehlende sofortige Interoperabilität mit C/C++-Libraries, ohne selbst Adapter zu schreiben. Es wäre schön, wenn man einfach Header importieren könnte und fertig.
    Auch mit Rust wäre eine ähnlich einfache Interoperabilität wünschenswert. Das könnte die Verbreitung erhöhen, weil es in Rust leichter ist, hochwertige Cross-Platform-Crates zu finden, die auch auf Mobilgeräten ohne große Probleme laufen.
    Ich mache mir Sorgen, dass Python in ein paar Jahren mit schnellerer Ausführung, entferntem GIL, nuitka und briefcase für Mobile aufholt – oder dass Mojo Nim den Platz streitig macht.

    • Zur Verteidigung von Nim: Praktisch nur Python hat ein riesiges Machine-Learning-Ökosystem mit numpy, scipy, pandas, opencv, pytorch, tensorflow, keras und Ähnlichem. ML/AI-artige Arbeit in einer anderen Sprache als Python zu machen, ist wirklich schwer.
      Dennoch gibt es in Nim die Library nimpy, die eine nahezu nahtlose Interoperabilität mit Python bietet. Das heißt, man kann PyTorch, scipy und opencv einfach importieren und in Nim verwenden.
  • Ich wäre neugierig, ob jemand praktische Erfahrung mit Nim und Zig hat. Ich würde gern hören, inwiefern sie ähnlich sind und worin sie sich unterscheiden. Außerdem würde ich gern Benchmarks idiomatischer Webserver in beiden Sprachen auf Basis von Nim v2 sehen

    • Ich habe beide in einem Hobby-OS-Projekt verwendet: Nim[1] und Zig[2]. Ich bevorzuge Nim deutlich. Der Code ist knapp und elegant und lässt mich auf die Kernlogik konzentrieren, statt mit der Sprache zu kämpfen
      Zig ist ebenfalls gut, und mir gefallen die Unterstützung für optionale Werte sowie der Ansatz zur Fehlerbehandlung. Aber die laute Syntax, etwa !?[]u8 für eine Error-Union eines optionalen Zeigers auf einen Slice von uint8, hat mich abgeschreckt
      Dass man in den meisten Codeabschnitten, die dynamische Allokation brauchen, einen Allocator vorbereiten und weiterreichen muss, lenkt ebenfalls von der Kernlogik ab. Selbst kleine Aufgaben wie String-Verkettung oder Formatierung werden zur Arbeit
      Zig hat außerdem kein dynamisches Dispatching, was polymorphen Code schwierig macht; man muss mit irgendeiner Form von Duck Typing darum herumarbeiten. Am Ende habe ich entschieden, dass Zig nicht zu mir passt
      [1] https://github.com/khaledh/axiom
      [2] https://github.com/khaledh/axiom-zig
    • Ich pflege automatisch generierte Bindings für meine C-Bibliothek für Zig, Nim, Odin und Rust. Die Rust-Bindings müssten definitiv überarbeitet werden, damit sie idiomatischer werden
      Wenn man sich die Beispiele ansieht, ist es im Grunde derselbe Code in mehreren Sprachen; man bekommt also das große Bild, aber bei den Sprachfeatures kratzt es nur an der Oberfläche. Das Zig-Beispiel nutzt etwa keine comptime-Features
      Zig: https://github.com/floooh/sokol-zig/tree/master/src/examples
      Nim: https://github.com/floooh/sokol-nim/tree/master/examples
      Odin: https://github.com/floooh/sokol-odin/tree/main/examples
      Rust: https://github.com/floooh/sokol-rust/tree/main/examples
    • Ich habe Programme in beiden geschrieben, aber Nim schon eine Weile nicht mehr benutzt. Ich glaube, Nim hat beim Schreiben von Code mehr Spaß gemacht
      Zig ist langweiliger, aber aus lauter guten Gründen. Persönlich würde ich kein OS in Nim schreiben, aber Zig dürfte dafür großartig sein, sobald es ausgereifter ist. Ich habe angefangen, es für Embedded-Software zu verwenden
      Nim würde ich für CLI-Tools, Server-Anwendungen und vielleicht auch GUI-Anwendungen und Spiele einsetzen
      Das Zig-Team scheint deutlich mehr Aufwand in die gesamte Compiler-Infrastruktur zu stecken, und meiner Erfahrung nach ist das wirklich beeindruckend. Es gibt dort großartige Innovationen
    • Ich habe sowohl Nim als auch Zig in neuen Projekten ausprobiert. Es gibt viele konkrete Unterschiede, aber wenn man es einfach charakterisieren will: Nim ist eher der Versuch, ein Python-ähnliches Schweizer Taschenmesser als kompilierte Sprache zu bauen
      Zig ist eine viel fokussiertere Sprache, die auf eine bestimmte Nische zielt: Nachfolger und Ersatz für C zu sein. Und dieses Ziel trifft sie hervorragend
      Sprachpräferenzen hängen meiner Meinung nach von den persönlichen Bedürfnissen und Wünschen ab, die die aktuell verwendeten Sprachen nicht erfüllen. Ich bin bei Zig gelandet, weil mich der Ansatz als C-Nachfolger interessiert, aber ich verstehe auch, warum andere Nim wählen
    • Zig scheint keine Implementierung für die TechEmpower Benchmarks zu haben, Nim dagegen schon: https://www.techempower.com/benchmarks/#section=data-r21&l=y...