← Back to context

Comment by jact

1 day ago

I worked briefly on extending an Go static site generator someone wrote for a client. The code was very clear and easy to read, but difficult to extend due to the many rough edges with the language. Simple changes required altering a lot of code in ways that were not immediately obvious. The ability to encapsulate and abstract is hindered in the name of “simplicity.” Abstraction is the primary way we achieve simple and easy to extend code. John Ousterhoust defined a complex program as one that is difficult to extend rather than necessarily being large or difficult to understand at scale. The average Go program seems to violate this principle a lot. Programs appear “simple” but extension proves difficult and fraught.

Go is a case of the emperor having no clothes. Telling people that they just don’t get it or that it’s a different way of doing things just doesn’t convince me. The only thing it has going for it is a simple dev experience.

I find the way people talk about Go super weird. If people have criticisms people almost always respond that the language is just "fine" and people kind of shame you for wanting it. People say Go is simpler but having to write a for loop to get the list of keys of a map is not simpler.

  • I agree with your point, but you'll have to update your example of something go can't do

    > having to write a for loop to get the list of keys of a map

    We now have the stdlib "maps" package, you can do:

       keys := slices.Collect(maps.Keys(someMap))
    

    With the wonder of generics, it's finally possible to implement that.

    Now if only Go was consistent about methods vs functions, maybe then we could have "keys := someMap.Keys()" instead of it being a weird mix like `http.Request.Headers.Set("key", "value")` but `map["key"] = "value"`

    Or 'close(chan x)' but 'file.Close()', etc etc.

    • I haven't use Go since 2024, but I was going to say something similar--seems like I was pretty happy doing all my Functional style coding in Go. The problem for me was the client didn't want us to use it. We were given the choice between Java (ugh) and Python to build APIs. We chose Python because I cross my arms and bite my lip and refuse to write anymore Java in these days of containers as the portability. I never really liked Java, or maybe I never really like the kinds of jobs you get using Java? <-- that

    • Fair I stopped using Go pre-generics so I am pretty out of date. I just remember having this conversation about generics and at the time there was a large anti-generics group. Is it a lot better with generics? I was worried that a lot of the library code was already written pre-generics.

      1 reply →

    • > Now if only Go was consistent about methods vs functions

      This also hurts discoverability. `slices`, `maps`, `iter`, `sort` are all top-level packages you simply need to know about to work efficiently with iteration. You cannot just `items.sort().map(foo)`, guided and discoverable by auto-completion.

    • > Now if only Go was consistent about methods vs functions

      Generics can only be on function and not methods because of it's type system. So don't hold your breath and modifying this would be a breaking change.

  • Ooh! Or remember when a bunch of people acted like they had ascended to heaven for looking down on syntax-highlighting because Rob said something about it being a distraction? Or the swarms blasting me for insisting GOPATH was a nightmare that could only be born of Google's hubris (literally at the same time that `godep` was a thing and Kubernetes was spending significant efforts just fucking dealing with GOPATH.).

    Happy to not be in that community, happy to not have to write (or read) Go these days.

    And frankly, most of the time I see people gushing about Go, it's for features that trivially exist in most languages that aren't C, or are entirely subjective like "it's easy" (while ignoring, you know, reality).

So you used Go once, briefly, and yet you feel competent to pass this judgement so easily?

As someone who's been doing Go since 2015, working on dozens of large codebases counting probably a million lines total, across multiple teams, your criticisms do not ring true.

Go is no worse than C when it comes to extensibility, or C# or Java for that matter. Go programs are only extensible to the extent (ha) developers design their codebases right. Certainly, Go trades expressivity for explicitness more than some languages. You're encouraged to have fewer layers of abstraction and be more concrete and explicit. But in no way does that impede being able to extend code. The ability to write modular, extensible programs is a skill that must be learned, not something a programming language gives you for free.

It sounds like you worked on a poorly constructed codebase and assumed it was Go's fault.

  • It certainly isn’t impossible to write good code in Go. Perhaps the code base I was working on was bad — it didn’t seem obvious to me that it was. Go is not a bad language in the way that brainfuck is a bad language.

    I think Java and C# offer clearly more straightforward ways to extend and modify existing code. Maybe the primary ways extension in Java and C# works are not quite the right ones for every situation.

    The primary skill necessary to write modular code is first knowing what the modular interfaces is and second being able to implement it in a clean fashion. Go does offer a form of interfaces. But precisely because it encourages you to be highly explicit and avoid abstraction, it can make it difficult for you to implement the right abstraction and therefore complicate the modular interfaces.

    Programming is hard. I don’t think adopting a kind of ascetic language like Go makes programming easier overall. Maybe it’s harder to be an architecture astronaut in Go, but only by eliminating entire classes of abstraction that are sometimes just necessary. Sometimes, inheritance is the right abstraction. Sometimes, you really need highly generic and polymorphic code (see some of the other comments for issues with Go’s implementation of generics).