5 Punkte von GN⁺ 2025-08-23 | 1 Kommentare | Auf WhatsApp teilen
  • Mehrere Entscheidungen im Sprachdesign von Go wurden unnötig getroffen oder unter Ignorieren bestehender Erfahrungen gefällt
  • Das Problem der Verwaltung des Gültigkeitsbereichs von Fehler-Variablen erschwert die Lesbarkeit des Codes und das Auffinden von Bugs
  • In mehreren Bereichen wie der Doppelnatur von nil, Speicherverbrauch und Code-Portabilität zeigt sich ein unintuitives Design, das nicht zur Praxis passt
  • Die Grenzen der defer-Anweisung und die Art der Ausnahmebehandlung in der Standardbibliothek erschweren es, Exception-Sicherheit zu gewährleisten
  • Aufgestaute Probleme wie mangelhafte Speicherverwaltung und UTF-8-Verarbeitung wirken sich langfristig negativ auf die Qualität von Go-Codebasen aus

Langfristige Kritik an der Go-Sprache

  • Wie ich bereits in früheren Beiträgen (Why Go is not my favourite language, Go programs are not portable) dargelegt habe, weise ich seit mehr als zehn Jahren auf verschiedene Probleme der Go-Sprache hin
  • Besonders bedauerlich wirkt, dass unnötige Designentscheidungen, die bekannte Good Practices ignorieren, immer stärker ins Gewicht fallen

Die Unintuitivität des Gültigkeitsbereichs von Fehler-Variablen

  • Die Go-Syntax erweitert den Gültigkeitsbereich der Fehler-Variable (err) unnötig und erhöht damit die Wahrscheinlichkeit von Fehlern
    • Im Beispielcode lebt die Variable err über die gesamte Funktion hinweg weiter und wird wiederverwendet, was Lesbarkeit und Wartbarkeit des Codes verschlechtert
    • Selbst erfahrene Entwickler erleben durch solche Scope-Probleme Missverständnisse und Zeitverlust bei der Fehlersuche
    • Eine Möglichkeit, Variablen angemessen lokal zu begrenzen, wird von der Syntax nicht zugelassen

Zwei Formen von nil

  • In Go gibt es die verwirrende Situation, dass nil bei Interface-Typen und Pointer-Typen unterschiedlich funktioniert
    • Wie im folgenden Beispiel führen Zuweisungen von nil an s (Pointer) und i (Interface) zu inkonsistentem Verhalten, etwa weil s==i unterschiedlich ausgewertet wird
    • Das ist ein Problem, das man bei der Behandlung von null-Werten normalerweise vermeiden möchte, und wirkt wie das Ergebnis unzureichender Überlegungen im Design

Grenzen der Portabilität von Code

  • Die Verwendung von Kommentaren für bedingte Kompilierung ist im Hinblick auf Wartbarkeit und Portabilität deutlich ineffizient
    • Wer tatsächlich schon portable Software gebaut hat, weiß, dass dieser Ansatz umständlich und fehleranfällig ist
    • Historisch gewachsene Erfahrungen zu Code-Portabilität und praktischen Fällen werden ignoriert
    • Siehe dazu Go programs are not portable

Unklare Besitzverhältnisse bei append

  • Die Beziehung zwischen der Funktion append und dem Besitz von Slices ist nicht klar, wodurch sich Code schwer vorhersagen lässt
    • Anhand eines Beispiels wird gezeigt, dass sich vorab schwer erkennen lässt, welchen Einfluss ein append auf einen Slice in der Funktion foo tatsächlich auf das Original hat
    • Dadurch nimmt die Zahl sprachlicher „quirks“ zu, die man kennen muss, und das führt zu Fehlern

Unzureichendes Design der defer-Anweisung

  • Es gibt keine klare Unterstützung für das Freigeben von Ressourcen nach dem RAII-Prinzip (Resource Acquisition Is Initialization)
    • Im Vergleich zu strukturierten Resource-Management-Konstrukten in Java und Python ist in Go nicht klar erkennbar, welche Ressourcen mit defer freigegeben werden sollten
    • Wie das Beispiel mit Dateiverarbeitung zeigt, muss man sogar Probleme wie Double-Close selbst behandeln, und die richtige Reihenfolge sowie Art der Freigabe bleiben unklar

Ausnahmebehandlung in der Standardbibliothek

  • Go ist strukturell so angelegt, dass es keine expliziten Exceptions unterstützt, dennoch treten Ausnahmefälle wie panic weiterhin auf
    • In manchen Situationen beendet panic das Programm nicht vollständig, sondern wird gewissermaßen verschluckt
    • In der Standardbibliothek (fmt.Print, HTTP-Server usw.) existieren Muster, in denen Ausnahmen ignoriert werden, sodass echte Exception-Sicherheit nicht garantiert werden kann
    • Am Ende ist exception-sicherer Code zwar zwingend nötig, aber Exceptions selbst lassen sich nicht direkt verwenden

UTF-8-Verarbeitung und Strings

  • Selbst wenn man beliebige Binärdaten in den Typ string steckt, arbeitet Go ohne besondere Validierung weiter
    • Dadurch kann es vorkommen, dass Dateinamen aus der Zeit vor UTF-8 stillschweigend ausgelassen werden
    • Bei Backups und ähnlichen Szenarien können wichtige Daten verloren gehen; der Ansatz ist zu simpel und spiegelt reale Anforderungen nicht wider

Grenzen der Speicherverwaltung

  • Eine direkte Kontrolle über den RAM-Verbrauch ist schwierig, und auch die Zuverlässigkeit des GC (Garbage Collector) hat Grenzen
    • Der Speicherverbrauch von Go wächst, was langfristig zu Kosten- und Performance-Problemen führt
    • In Umgebungen mit mehreren Instanzen oder Containern treten Kosten- und Skalierungsprobleme tatsächlich auf

Fazit: Es hätte einen besseren Weg gegeben

  • Obwohl es bereits wirksam erprobte Sprachdesigns gab, ignoriert Go sie in vielen Punkten
    • Anders als bei den Problemen früher Java-Entwürfe gab es zum Zeitpunkt der Veröffentlichung von Go bereits bessere Ansätze

Referenzen

1 Kommentare

 
GN⁺ 2025-08-23
Hacker-News-Kommentar
  • Ich nutze Go seit der Zeit vor 1.0 in fast jedem Vollzeitjob. Für Teammitglieder ist es einfach, die Grundlagen zu lernen, und es läuft meist stabil. Beim Update auf die neueste Go-Version muss man sich fast nie Sorgen machen, und die meisten nützlichen Funktionen sind standardmäßig enthalten. Die schnelle Kompilierung ist attraktiv. Nebenläufigkeit ist etwas knifflig, aber wenn man Zeit investiert, eignet es sich gut dazu, Datenflüsse auszudrücken. Das Typsystem ist meist praktisch, aber manchmal etwas wortreich. Insgesamt ist es ein verlässliches Werkzeug. Trotzdem kann ich viele der im Artikel genannten Kritikpunkte nachvollziehen. Es ist klar, dass Go an einigen Stellen zu sehr von Entwicklern der alten Schule geprägt wurde, die sich an Prinzipien festgebissen und dabei praktische Bequemlichkeit verpasst haben. Das ist natürlich nur mein Eindruck, und ich denke auch, wenn man alle Schwächen behoben hätte, wäre es vielleicht heute schlechter. Ich möchte außerdem erwähnen, dass die Stimmung in den letzten Jahren offener für das Beheben solcher Eigenheiten geworden ist. Früher hätte ich mir nie vorstellen können, dass Generics oder benutzerdefinierte Iteratoren hinzukommen. Die Kritik an RAM und Portabilität wirkt eher wie persönlicher Frust. Verbesserungen wären schön, aber dass der GC in den meisten Programmen ernsthafte Probleme verursacht, ist extrem selten, und Debugging ist auch nicht besonders schwer. Außerdem unterstützt Go fast alle wichtigen Plattformen. Allerdings stören mich Fehler- und nil-Behandlung weiterhin. Syntax wie Result[Ok, Err] oder Optional[T] vermisse ich oft

    • Ich sehe eher das Gegenteil: Go hat nicht stur an Prinzipien festgehalten, sondern sich an der Bequemlichkeit festgebissen, sichtbare Probleme schnell zu lösen. Statt Probleme grundlegend zu analysieren und korrekt zu lösen, wirkte es so, als hätte man den Geist von „Not Invented Here“ aufgegeben und schnell etwas zusammengeschustert. Die Dateisystem-API von Go ist ein typisches Beispiel. Man braucht eine Funktion zum Öffnen von Dateien, also macht man einfach func Open(name string) (*File, error) und fertig. Aber was, wenn der Dateiname nicht UTF-8 ist? Wenn das Problem fünf Jahre lang nicht auftaucht, kümmert man sich eben nicht darum

    • Ich habe oft das Gefühl, dass die Designprinzipien von Go zu stark auf das Ziel „Compiler einfach halten und Kompilierung schnell machen“ fokussiert sind. Die Struktur ist stärker auf Compiler und Kompilierung selbst ausgerichtet als auf Entwickler-Ergonomie

    • Nach 20 Jahren habe ich in einem neuen Job zum ersten Mal wieder ernsthaft eine kompilierte Sprache benutzt, nämlich Go. Vielleicht Geschmackssache, aber ehrlich gesagt hat sich das beim Schreiben teils unerquicklich angefühlt. Keine Standardargumente, die Fehlerbehandlung gefällt mir nicht, keine ordentlichen Stacktraces in Produktion. Die objektorientierte Syntax sieht unschön aus, weil man an jede Funktion diese merkwürdige Referenz hängen muss. Auch Zeiger sind lästig. Es fühlt sich letztlich an, als wäre man zu alten C/C++-Techniken zurückgekehrt. Genau die Programmieratmosphäre, die ich um 1999 im Studium hatte

    • Was Nebenläufigkeit angeht, ist Go meiner Erfahrung nach das einzige System, das Parallelität in einer Mehrkern-CPU-Umgebung sprachlich natürlich behandelt. Dank des CSP-artigen Goroutine/Channel-Modells lässt sich Nebenläufigkeitslogik intuitiv ausdrücken. Python ist mit GIL und kryptischen Async-Bibliotheken unerquicklich. Bei C, C++, Java usw. braucht man zusätzliche Bibliotheken außerhalb der Sprache, daher ist Schlussfolgern über Parallelität auf Sprachebene nicht einfach. Deshalb passt Go meiner Meinung nach perfekt zu HTTP-Servern oder Services. Ich kenne aus meiner Erfahrung keine ähnlich gute Alternative

    • Aus Entwicklersicht war die Ergonomie, also Standardisierung und Konsistenz, nahezu perfekt. Selbst über mehrere Microservice-Codebasen hinweg muss man sich keine Sorgen um unterschiedliche Stile machen, und Formatierungsdebatten entfallen. Allerdings scheint Go bei der Wahl seines eigenen Standards etwas zu sehr an alten Mustern festzuhalten. Heutige Entwickler erwarten eher funktionale Methoden wie map/filter, während Go nur Schleifen bietet, bei denen man sich leicht bei Indizes vertut. Das Typsystem ist auch nicht so intelligent wie etwa in TypeScript. Die Fehlerbehandlung ist umständlich. Ich verstehe die Sorge, dass zusätzliche Features mehr „kreative, aber schlechte Nutzungsweisen“ fördern könnten, aber mir ist auch klar geworden, dass es schwer ist, die JS-Generation von Go zu überzeugen

  • Ich arbeite seit über fünf Jahren intensiv an großen Golang-Projekten, und wenn man Komponenten bauen muss, bei denen der Speicherverbrauch minimiert werden soll, stößt man oft auf die schlampigen Seiten von Go. Der GC räumt nicht schnell genug auf oder die Heap-Fragmentierung wird schlimm, weil Go keinen kompaktierenden Garbage Collector hat. Deshalb versuchen wir, Allokationen vollständig zu vermeiden, was aber fehleranfällig ist. Auch Debugging ist extrem mühsam. Heap-Profile zeigen nur Informationen zu überlebenden Objekten, nicht aber den tatsächlich aufgelaufenen Müll oder Fragmentierungsdetails, sodass man auf Vermutungen angewiesen ist. Zum Beispiel zeigt eine Funktion X vielleicht nur 1 KB Heap-Allokation an, aber wenn sie in einer Schleife ständig aufgerufen wird, entstehen zig MB Müll. Also allokiert man vorab statische Buffer und verwendet sie wieder, aber dann werden Eigentumsfragen kompliziert und Lücken wie append tun sich auf. Man muss teils sogar die Standardbibliothek selbst neu implementieren. Ich weiß auch, dass unser Fall nicht typisch ist, aber es ist schade, weil es sich wirklich anfühlt, als würde man gegen die Sprache kämpfen

    • In solchen Fällen kann es sogar weniger schmerzhaft sein, den Speicher außerhalb des Heaps zu verlagern. In einer GC-Sprache ist das natürlich nicht einfach, aber statt krampfhaft C++-/Rust-artigen Code in Go nachzubauen, wäre es besser, genau diesen Teil gleich in der jeweiligen Sprache umzusetzen

    • Wenn man in so einer Situation Go gewählt hat, war die Sprachwahl selbst wohl das Problem. C/C++/Rust/Zig wären dafür besser geeignet

    • Es gibt Hinweise, dass der neue Garbage Collector „Green Tea“ helfen könnte. Er ist zwar nicht primär auf Speicher optimiert, aber ein paralleler Markierungsalgorithmus, der mit speicherbenachbarten Objekten besser umgeht. Weitere Informationen gibt es hier

    • Das Arena-Experiment lief zwar eine Zeit lang, ist derzeit aber gestoppt. Trotzdem interessant genug, um es sich anzusehen

    • Sorry, dass das nicht besonders hilfreich ist, aber angesichts der aktuellen Lage denke ich, dass die Sprachwahl komplett falsch war. Ich vermute, dass ihr Go nur wegen einer offiziellen Sprachrichtlinie im Unternehmen erzwingt. In großen Firmen wird Produktion oft nur für weit verbreitete Sprachen freigegeben

  • Ich verstehe bis heute nicht, warum defer in Go nur auf Funktions-Scope und nicht auf lexikalischen Scope wirkt. Gemerkt habe ich mir das, nachdem ich in einer Schleife Dateien verarbeitet habe, die Dateiliste groß wurde und defer die Handles nicht vor Funktionsende schloss, was zu einem Crash führte. Andere Go-Entwickler meinten dann, ich solle einfach den Schleifenrumpf in eine anonyme Funktion packen. Abgesehen von ein paar kleineren Punkten fühlt sich Go ansonsten angenehm an, hat eine effiziente Syntax und verhindert auch unnötige „Angeber“-Kultur. Ich habe einmal ein großes C#-Projekt in Go neu geschrieben; obwohl es nur ein Zehntel des Funktionsumfangs hatte, war der Code trotzdem kürzer. Statt GC-Allokationen zu erzwingen, lenkt Go einen dazu, standardmäßig performante Muster zu verwenden, und eingebaute Codegenerierung für Dinge wie Serialisierung ist praktisch. Anders als bei der C#-Syntax, die alles durch die Sprache selbst ersetzen will, schreibt man in Go SQL einfach als SQL, und gRPC wird über die protobuf-Spezifikation abgewickelt

    • Manchmal braucht man defer auf lexikalischem Scope, manchmal auf Funktions-Scope. Wenn man zum Beispiel in einer Schleife mehrere Dateien öffnet und sie bis zum Ende der Funktion alle offen halten will, braucht man Funktions-Scope. Aktuell ist es eben Funktions-Scope; wenn man lexikalischen Scope braucht, kann man mit func kapseln. Wenn nur lexikalischer Scope unterstützt würde und man Funktions-Scope bräuchte, wäre unklar, wie man das lösen sollte

    • Vorteile sind, dass man ohne Wrapper-Funktion eine zusätzliche Einrückungsebene spart, dass das Verhalten mit Call-Stack und Stack-Unwinding zusammenhängt und dass es aus Sicht des C-Stils mit goto fail natürlich wirkt. Klar, in Schleifen ist defer etwas unpraktisch, weil man dort extra in eine Funktion kapseln muss

    • Ich habe sowohl Sprachen mit Block-Level- als auch mit Function-Level-defer benutzt, und manchmal wünschte ich, man könnte auch in if-Blöcken Function-Level-defer verwenden

    • Ich glaube nicht, dass es dafür einen besonders tiefen Grund gibt, und frage mich, ob das in der Praxis überhaupt wichtig ist

    • Auch in C# kann man mit SQL oder protobuf-Spezifikationen arbeiten. Der Unterschied ist nur, dass es daneben noch andere Optionen gibt

  • Go hat viele Schwächen, aber in der Kategorie serverseitiger Sprachen wirkt es auf mich wie die ausgewogenste Sprache. Es ist schneller als Node oder Python, und das Typsystem ist meiner Meinung nach auch besser. Die Einstiegshürde ist niedriger als bei Rust, und Standardbibliothek sowie Tooling sind hervorragend. Ich mag die einfache Syntax und dass im Grunde ein einziger Weg vorgegeben wird. Die Fehlerbehandlung ist problematisch, aber immer noch besser als bei Node, wo in catch sonstwas landen kann. Ich frage mich, ob es noch eine bessere Sprache gibt, die all diese Kriterien erfüllt. Ich bin kein Go-Fanatiker; ich habe den Großteil meiner Laufbahn Backend mit Node gemacht, experimentiere aber in letzter Zeit mit Go

    • Eigentlich ließen sich all diese Vorteile genauso auf Java oder C# anwenden

    • Mich stört schon, Node als Programmiersprache zu bezeichnen. Node ist eine JavaScript-Runtime, und viele heutige Projekte auf Node sind in TypeScript geschrieben. Das heißt: Wenn man Node sagt, ist die verwendete Sprache gar nicht eindeutig. Nimmt man TypeScript als Maßstab, finde ich dessen Typsystem sogar produktiver als das von Go. Dasselbe Argument lässt sich auch im Vergleich zu Rust machen

    • Die meisten Sprachen haben ihre eigenen unbequemen Seiten. Go punktet mit Performance, Portabilität sowie Laufzeit und Ökosystem. Andererseits hat es Nachteile wie nil-Pointer, Zero Values, keine Destruktoren und keine Makros; das Fehlen von Makros wird in Go oft durch exzessive Codegenerierung umgangen. Es gibt bessere Sprachen, etwa Rust, aber die sind dann auch deutlich komplexer als Go. Der Grund dafür ist, dass die Go-Macher Einfachheit über alles gestellt haben

    • Wenn man die jüngsten Fortschritte beim Typsystem von Python berücksichtigt, liegt es meiner Ansicht nach weit vor Go. Allein beim Structural Typing ist Python beeindruckender

    • Ich halte das Typsystem von Go für ziemlich unzureichend

  • Ich habe einmal einen in Go geschriebenen Static Site Generator erweitert. Der Code war sehr klar und gut lesbar, aber wegen sprachlicher Lücken schlecht erweiterbar. Selbst einfache Änderungen zwangen dazu, an vielen Stellen mühsam umzubauen. Verschiedene Ebenen von Kapselung und Abstraktion sind schwierig, und zugunsten von „Einfachheit“ wird Abstraktion geopfert. Dabei ist Abstraktion der wichtigste Weg, Code zu schreiben, der leicht erweitert werden kann. Go entscheidet sich also für Einfachheit statt Erweiterbarkeit. Meist wirkt ein Go-Programm auf mich wie „einfache, aber nicht erweiterbare“ Software. Viele sagen dann einfach, Go sei eben so, aber meine Erfahrung überzeugt mich davon nicht. Immerhin ist die „Developer Experience“ nicht schlecht

    • Gespräche über Go fühlen sich immer etwas seltsam an. Wenn man Kritik übt, kommt meist nur „die Sprache ist halt so“, und man soll sich damit abfinden. Einfachheit wird als Stärke verkauft, aber ist es wirklich einfacher, eine Schlüsselliste aus einer Map zu bekommen, wenn man dafür selbst eine Schleife schreiben muss?

    • Ich frage mich, ob man nach nur kurzem Kontakt mit Go wirklich so ein Urteil fällen kann. Ich arbeite seit 2015 mit zahlreichen großen Go-Codebasen in der Größenordnung von Millionen Zeilen und in mehreren Teams. Was Erweiterbarkeit angeht, ist Go im Vergleich zu C, C# oder Java keineswegs besonders schwach. Go bevorzugt Klarheit gegenüber Ausdrucksstärke. Deshalb hat man weniger Abstraktionsschichten und gewöhnt sich daran, konkreter und expliziter zu schreiben. Aber ich sehe darin keinen Beleg, dass es nicht erweiterbar sei. Modulare, erweiterbare Architektur ist eher etwas, das Entwickler lernen und umsetzen, nicht etwas, das die Sprache allein liefert. Vielleicht war der Code, den du bearbeitet hast, einfach schlecht entworfen; das ist keine Grenze der Sprache selbst

  • Ich habe Go einige Jahre lang verwendet. Kleine Dinge kann man schnell bauen, aber je größer das Projekt wird, desto mehr leidet man unter unzähligen kleinen Unbequemlichkeiten. Besonders Debugging ist ein Albtraum: Wenn es ein unbenutztes X gibt, was beim Auskommentieren einzelner Stellen während des Debuggens ständig passiert, kompiliert das Programm überhaupt nicht mehr. Auch unnötige Förmlichkeit, spezielle Dateinamen und viele reservierte Feldnamen sind lästig. Versteckte panics in der Standardbibliothek und unerwartete Heap-Kopien machen es ebenfalls langsam und nervig. Die „magischen“ Teile von Go sind meist Nebenwirkungen davon, dass man bestehende Mechanismen wie spezielle Dateinamen oder Groß-/Kleinschreibung zweckentfremdet hat. Wenn etwas wirklich public sein soll, hätte man auch einfach pub schreiben können; diese Sturheit wirkt seltsam. Heute ist KI so gut, dass ich bei Typfehlern oder Borrow-Checker-Problemen in Rust direkt die KI frage und schnell weiterkomme. Ich muss nicht mehr wie früher Zeit damit vergeuden, Dokumentation oder Stack Overflow zu durchforsten

    • Ich habe Rust noch nicht intensiv verwendet, aber als ich es letzten Dezember kurz ausprobierte, war ich überrascht, wie gut KI mit Rust zurechtkommt. Gerade weil es so viele präzise Syntaxdetails und explizite Typinformationen gibt, löst KI das teils besser als Menschen

    • Wenn man sich in Go über Compile-Fehler beim Debuggen beschwert, bekommt man aus dem Go-Lager oft nur zu hören, man solle eben die richtigen Tools benutzen. Prinzipien werden dort zu extrem durchgezogen, und das ist unerquicklich

    • Ich habe diese Debugging-Unbequemlichkeit einmal einem der Go-Erfinder geschildert, aber selbst der konnte das Problem nicht nachvollziehen. Das wirkte sehr amateurhaft und war enttäuschend. Übrigens ist KI in Go eher nicht so gut. Obwohl die Sprache recht einfach ist, unterstützt ChatGPT Java, C# und Python besser

  • Persönlich mag ich Go nicht besonders und sehe viele gravierende Schwächen, aber warum es weiter so beliebt ist, ist klar. Go ist relativ schnell und erlaubt dank Goroutines, auch ohne Multithreading stabile und zuverlässige hochgradig nebenläufige Services einfach zu schreiben. Als Google Go veröffentlichte, gab es kaum vergleichbare populäre, statische, kompilierte Sprachen. Selbst heute ist Java der einzige ernsthafte Konkurrent in ähnlicher Position, inzwischen mit Virtual Threads. Sprachen mit async/await versprechen Ähnliches, bringen in der Praxis aber viel Komplexität mit, etwa kein Blocking in asynchronen Tasks oder die bekannte Function Coloring. Erlang ist wieder eine andere Kategorie. Letztlich bleibt Go trotz seiner vielen Schwächen wegen Goroutines und der Strahlkraft eines Google-Projekts populär

    • Die JVM verringert den Abstand zu Go schrittweise. Mit Projekten wie Virtual Threads, zgc, lilliput, Leyden und Valhalla wird sie immer besser. Der Wandel von Java 8 zu 25 ist enorm. In Zukunft dürfte es noch komfortabler werden

    • Gos Explizitheit und Einfachheit passen sehr gut zu LLM-gestütztem Programmieren. Alter Go-1.x-Code läuft auch heute noch problemlos auf aktuellen Versionen

    • Tatsächlich wird intern bei Google Java mit Virtual Threads viel häufiger verwendet als Go

    • Mich würde interessieren, welche „moderne Sprache“ du für neue Projekte am geeignetsten hältst

  • Ich mochte Go schon vor 1.0, aber der Vorwurf „es ist immer noch nicht fertig“ leuchtet mir nicht ein. Natürlich gibt es Schwächen und Frustpunkte, aber wenn die Gründer ein Projekt verlassen, wird es auch schwerer, eine zentrale Vision zu halten, und das Risiko steigt, dass die Sprache schlechter wird. Dass Go nur als „Serversprache“ positioniert wird, dürfte am Ende eher dazu führen, dass Leute zu Rust oder Python abwandern. Über Visual Basic wurde früher auch gespottet, und trotzdem haben die Leute, die es brauchten, gut damit gearbeitet

  • Wenn man kritische Texte über die Schwächen von Go genau prüft, sind viele Punkte eigentlich keine große Sache. Meist sind sie technisch korrekt, aber eher nebensächlich. Wirklich gravierende Sprachdesign-Probleme sind stattdessen Zero Values, fehlende Unterstützung für Konstruktoren, schwache Null-Behandlung, standardmäßige Mutability, ein nicht mit Blick auf Generics entworfenes Typsystem, int ohne beliebige Präzision und Slices mit unklaren Eigentumsverhältnissen (relevantes Issue 1, relevantes Issue 2). Auch fehlende Sum Types und keine String-Interpolation sind Nachteile

  • Ich bin vielleicht voreingenommen genug, um ein Buch über Go zu schreiben, aber nach mehr als zehn Jahren mit Go erinnere ich mich noch gut daran, wie frisch es sich anfangs anfühlte. Weniger Boilerplate als Java, leicht zu lernen und ordentliche Performance. Die beste Sprache gibt es nicht; je nach Einsatzzweck gibt es die passendste Wahl. Für typische Backend-Arbeit ist Go aber eine Entscheidung, die man kaum bereut

    • Ich benutze zu Hause gern einen Dremel für DIY und Holzarbeiten; Go ist ähnlich leicht zugänglich und unkompliziert. Mit einem Dremel kann man schnell loslegen, ohne gleich die große Säge hervorzuholen. Aber wenn man nur mit dem Dremel arbeitet, dauert vieles am Ende fünfmal so lange und das Ergebnis wird womöglich unsauber. Ich nenne das für mich den „Dremel-Effekt“, um mich daran zu erinnern, dass man für ein wirklich gutes Ergebnis am Ende das richtige Werkzeug wählen muss