to Overview
Jan. 15, 2025

Go - how Opinions Differ on Simplicity

As software engineer I always recommended to keep code as simple as possible. And so I was quite open-minded about Go, which claimed to offer only the simplest features. And my default programming language is dead boring Java. So I expected to learn some elegant language concepts that make it easier to write and understand code.


First of all - what is wrong with Java? Is it too complex to understand? To be honest, I never considered Java syntax to be complex. Maybe I am biased. But from my viewpoint Java gets complex where the syntax does not prevent me from shooting myself in the foot:

  • Doing concurrency in Java correctly is really complex
  • Support for preventing null pointer exceptions is low
  • The mix of errors, exceptions and runtime exceptions is confusing (especially when there is no common consensus how to use them)
  • Support for immutable data is low
  • Syntax for functional features is verbose

Did Go try to fix any of these problems?

  • Gos concurrency is simpler, but the problems remain. Nothing in Go prevents me from accidentally writing code with data races.
  • Go does not in any way try to prevent null pointer exceptions.
  • Go does not use exceptions, which sounds promising, but it is a total mess. The language does not force one to handle an error; it does not even force one to recognize it. Some languages give the responsibility of memory management to the user (manual memory management) and Go gives the responsibility of error management to the user. A true step backward.
  • Go does not support immutability. Even Java allows one to initialize a variable with two (or more) different values dependent on some condition(s). In Go, we have to initialize a variable and then must overwrite this variable in an imperative conditional section.
  • Go does support functions. There is nothing wrong with that. Note that Go gives us functions but refuses to support immutability. So there must be a special Go type of functional programming here.

Ok, maybe my expectations were wrong. What did Go provide that I did not miss:

  • Only structs, arrays and maps - no classes, unions or tuples (no algebraic data types); maybe this really is sufficient?
  • Garbage collection - I am fine with that, but now Go should compare itself to Java.
  • Private methods start with lower case, public methods start with upper case - what a weird idea. Honestly, Javas modifiers can be confusing, especially after the introduction of the module system. Having only public and private methods is ok for me. But having to change the name dependent on visibility? What is the benefit?
  • Structural Typing - the idea that the name of a method determines its contract is fairly optimistic. I agree, that this should be true if the context is the same, but the latter condition is cannot be assumed in general.
  • No implementation inheritance - Nice. But together with structural typing this leads to some kind of weird polymorphism.
  • But you can omit semicolons at the end of statements - what should I say? Better say nothing.

So I come to the conclusion that the Go language was made for programmers that miss features that I do not want and that are willing to skip features I appreciate - what a pity. Fortunately - for those that dream of a better solution - there is Rust.