Hacker News new | ask | show | jobs
by iamcalledrob 1073 days ago
I am immensely thankful for Go.

The simplicity of the language and the stdlib is shockingly well thought out -- things like io.Reader are so obvious and yet not part of many other languages. The language has made me a better programmer. And the cross-compilation story is chefs kiss.

Working on a cross-platform project where in Go, I write code and it just builds. In Java, I fight with Gradle. In Swift, I fight the type system and the way everything's constantly deprecated.

It's not all perfect. I wish the generated binaries were smaller. I wish the protobuf library wasn't awful. And better Cgo/FFI would be nice.

But overall, I've never been so productive.

4 comments

It's the simplicity of the tooling for me. There's no config file besides a list of dependencies. I push my code to github and it can be a dependency because a dependency is just a URL. My code is automatically formatted and there's no config for that.
> Working on a cross-platform project where in Go, I write code and it just builds

I've worked on large golang code bases that had to build on bazel, and I had the same experience fighting it. It has nothing to do with the language.

> In Java, I fight with Gradle.

So gradle's issue, not Java's. See above.

Pretty much every golang project I've ever touched builds with `go build`. Most that have makefiles just call `go build`, and the makefile is more for building docker containers, or doing infra-related things. If a project is in go, 98% of the time `git clone XXX && cd XXX && go build` will work.

That is absolutely not the case with C, C++, Java, python.

> So gradle's issue, not Java's. See above.

The issue exists with maven too, but _not_ with go build, which is OP's point.

> If a project is in go, 98% of the time `git clone XXX && cd XXX && go build` will work.

I can’t speak for the other languages but I reckon this is the case for Java projects. Git clone, cd XXX, mvn clean package.

Potentially messing about with whether you have Java 8, 11 or 17 installed which saddens me to mention. But if you are into Java, you have them all installed already, and just need to make sure the right one is activated when you do the above steps.

> I've worked on large golang code bases that had to build on bazel, and I had the same experience fighting it. It has nothing to do with the language.

So you deliberately added complexity instead of using Go's own build system and it didn't work out well and that's somehow a proof that Go's cross-compilation story isn't as great as people say?

It wasn't my call on what they did, and they had their reasons (running one of the largest golang monorepos on the planet). My point was to show that this is a build tool issue, not a language issue.
The way you use the language has everything to do with the language. It is the language.

A language is a product, and the programmers writing in it are its users. The same way any other product works.

Would you be okay with buying a Tesla without the capability to charge at supercharger stations? You can only charge at home. The supercharger network is not literally part of the car after all!

> I wish the protobuf library wasn't awful

I’m curious what you don’t like about it? I haven’t used Go in anger, but I love protobufs, and it’s shocking that Go, of all languages, would have a substandard implementation.

My personal gripes are around the generated code not being idiomatic Go. It feels like code written by someone who doesn't really enjoy Go.

In particular, oneofs are *so* awful to work with that I'm often tempted to use an Any instead. For example:

    message Image {
      oneof kind {
        Bitmap bitmap = 1;
        Vector vector = 2;
      }
    }
Should, in my opinion, lead to code like this:

    img := &Image{Kind: &Bitmap{}}
But the reality looks more like this:

    img := &Image{Kind: &Image_Bitmap{Bitmap: &Bitmap{}}}

My other main gripe is that the generated structs embed a mutex, and so can't be copied, compared [ergonomically], or passed by value.

Sadly, both of these issues are explained away as on the issue tracker.

(My use-case is primarily to share data structures across languages, so perhaps it's not totally aligned with what protobufs is trying to do. I just wish there was a better alternative.)

Been a few years since I’ve used Go protobuf library, but it left a sour taste. First memory allocations are awful and slow. At the time there was no way to reuse slices for serializer when serializing and deserializing. The library would often panic instead of returning an error (this basically why we switched to an alternative library).
For me the biggest unsung hero is the _stability_

There's something so liberating about finding code samples or documentation from 5-10 years ago and it is still the correct way to solve a problem. The lack of churn in the ecosystem means you can learn the language and then focus on actually building stuff rather than focusing on the rat race of learning the latest hotness and restructuring your app constantly to account for dependencies that break things.