I know they say that your programming language isn't the bottleneck, but I remember sitting there being frustrated as a young dev that I couldn't parse faster in the languages I was using when I learned about Go.
It took a few more years before I actually got around to learning it and I have to say I've never picked up a language so quickly. (Which makes sense, it's got the smallest language spec of any of them)
I'm sure there are plenty of reasons this is wrong, but it feels like Go gets me 80% of the way to Rust with 20% of the effort.
Funny thing is that also makes it easier on LLM / AI... Tried a project a while ago both creating the same thing in Rust and Go. Go's worked from the start, while Rust's version needed a lot of LLM interventions and fixes to get it to compile.
We shall not talk about compile time / resource usage differences ;)
I mean, Rust is nice, but compared to when i learned it like 10 years ago, it really looks a lot more these days, like it took too much of a que from C++.
While Go syntax is still the same as it was 10 years ago with barely anything new. What may anger people but even so...
The only thing i love to see is reduce executable sizes because pushing large executables on a dinky upload line, to remove testing is not fun.
I like Go. Coming from Python, I appreciate having most things be explicit in nature vs. magical, and having concurrency not feel like a bolted on nightmare.
Writing microservices at $DAYJOB feels far easier and less guess-work, even if it requires more upfront code, because it’s clear what each piece does and why.
Glad to see that the bowling development team is focusing on deterministic tooling like language server protocol in gopls and using static analysis for automatically restoring code with go fix.
Recently I made the same assertions as to Go's advantage for LLM/AI orchestration.
It would not surprise me that Google (being the massive services company that it is) would have sent an internal memo instructing teams not to use the Python tool chain to produce production agents or tooling and use Golang.
Go would probably be my favorite language if it just had a few more features around functional programming. Specifically around immutability and nullness, and maybe exhaustive switch statements. Then it just might be perfect.
At work we use Uber’s NillAway, so that helps bit. https://github.com/uber-go/nilaway Though actually having the type system handle it would be nicer.
I was very skeptical of Go when I started learning it, but it quickly became my favourite language. I like how simple but powerful it is.
If I had a magic wand, the only things I would add is better nulability checks, add stack traces by default for errors, and exhaustive checks for sum types. Other than that, it does everything I want.
Go is my favorite programming language. I remember when I first found Go and it was because I was using Java back then and learnign Akka framework for concurrent programming . I realized Go was so much less code compared to Java and I could understand it effortlessly. Since then I have been using it very regularly but still I don't feel I am good at this language. But it helps me get the work done. Cheers to the 16th anniversary of Go.
I remember when Go was born, then, it turned out there was already another programming language called "Go!", but nobody cared, and everybody forgot about that other Go!. So, happy birthday, Go, and rest in peace, Go!
I recently finished my first ever side gig in Go - a web platform that organizes business processes between multiple actors. Got paid and more feature requests are coming in. Fronted with Caddy, the whole thing runs flawlessly on a $5 VPS. I love Go.
The Go codebases look all alike.
Not only the language has really few primitives but also the code conventions enforced by standard library, gofmt, and golangci-lint implies that the structure of code bases are very similar.
Many language communities can't even agree on the build tooling.
I use Go every day at work and it's still the first thing I reach for when completing personal projects. It gets better every year. Keep up the good work Go team!
I tried to use go in a project 6-7 years ago and was kind of shocked by needing to fetch packages directly from source control with a real absence of built in versioning. That turned me off and I went back to python. I gather that now there’s a new system with go modules. I should probably revisit it.
I am not really familiar with Go but I wonder where it would be without Google's support and maintenance. I have no doubt it is a solid language with some really smart people in programming language design behind it.
It is so much easy to release programming language but so much difficult to maintain and curate it over time.
Golang to me is a great runtime and very poor language. I could maybe get used to the C pointer-like syntax and to half of my code checking if err != nil, but the lack of classes is a step too far. The Golang idiomatic approach is to have a sprawling set of microservices talking to each other over the network, to manage complexity instead of having classes. This makes sense for things like systems agents (eg K8) but doesn't make sense for most applications because it complicates the development experience unnecessarily and monoliths are also easier to debug.
I would not use Golang for a big codebase with lots of business logic. Golang has not made a dent in Java usage at big companies, no large company is going to try replacing their Java codebases with Golang because there's no benefit, Java is almost as fast as Golang and has classes and actually has a richer set of concurrency primitives.
Microservices are entirely unrelated to classes and in no way endemic to go.
Go’s lack of inheritance is one of its bolder decisions and I think has been proven entirely correct in use.
Instead of the incidental complexity encouraged by pointless inheritance hierarchies we go back to structure which bundle data and behaviour and can compose them instead.
Favouring composition over inheritance is not a new idea nor did it come from the authors of Go.
Also the author of Java (Gosling) disagrees with you.
Oh wow, so it's already been 16 years since Google steamrolled the Go! language, which had existed a decade before Go and had every right to the name. This was when they were still pretending "do no evil" was their brand.
There may be no honor amongst thieves but there is honor amongst langdevs, and when they did Go! dirty, Google made clear which one they are.
Which obscures the type, making it harder to read the code. The only justification is that 16 years ago, some guy thought he was being clever. For 99.99% of code, it’s a worse syntax. Nobody does eight levels of pointer redirection in typical everyday code.
Been happily working in Go since 2014. My career has spanned C, Python, C#, Ruby, and a smattering of other languages, but am always quite fond and preferential towards Go.
It has been my go to language since 2020. I was given a task to complete in a week and my lead told just go through Go playground and write the code (it was some snmp receiver/transmit stuff). To my surprise it was so easy to learn, write and more importantly test. Only recent thing i have not learned is generics, hopefully will get their sooner. Coming from java background the things Go did felt so clever and just too good to believe
I'm thankful for Go because it was an easy first introduction to static typing.
I remember making a little web app and seeing the type errors pop up magically in all he right places where I missed things in my structs. It was a life-changing experience.
To me, Go is like Rust oversimplified beyond reason. It edits your code when you don't ask, removing things you just started; it lacks iterators -- every time you must write a big cycle instead. It lacks simple things like check if a key exists in a map.
Proponents say it has nothing under the hood. I see under-the-hood-magic happen every time.
1) The arrays append is one example. Try removing an element from an array - you must rely on some magic and awkward syntax, and there's no clear explanation what actually happens under the hood (all docs just show you that a slice is a pointer to a piece of vector).
2) enums creation is just nonsense
3) To make matters worse, at work we have a linter that forbids merging a branch if you a) don't do if err != nil for every case b) have >20 for & if/else clauses. This makes you split functions in many pieces, turning your code into enterprise Java.
It feels like, to implement same things, Go is 2x slower than in Rust.
On the positive side,
* interfaces are simpler, without some stricter Rust's limitations; the only problem with them is that in the using code, you can't tell one from a struct
* it's really fast to pick up, I needed just couple of days to see examples and start coding stuff.
I think Go would have been great with
* proper enums (I'll be fine if they have no wrapped data)
* sensible arrays & slices, without any magic and awkward syntax
I used to do Go in production for several years, along with Java and TypeScript event-loop backends. It was a breeze of fresh air, especially for new projects, where the Java conventions could be put to rest. But in such an environment, with mostly Java legacy, people did tend to bend Go to the Java idioms rendering the PR reviews very cumbersome.
From what I’ve experienced, if you need any fine-grained control over your data or allocations, precision on the type level, expressing nontrivial algorithms, Go is just too clumsy.
The more I read about how people use Go today and what issues people still have, the more I’m happy I picked Rust for almost everything. I even find it much more productive to write scripts in Rust than in Python or shell script. You just get it right very quickly and you don’t need to care about the idiosyncrasies of ancient tech debt that would otherwise creep into your new projects. And of course the outcome is way more maintainable.
Not saying that Rust hadn’t had its own warts, but most of them are made explicit. This is perhaps what I appreciate the most.
Intuitively, however, I still notice myself creating a new Python or shell script file when I need something quick, but then something doesn’t really work well the moment the logic gets a bit more complex, and I need to backtrack and refactor. With Rust, this hasn’t been an issue in my experience.
And intuitively, I still tend to think in Java terms when designing. It’s funny how it sticks for so long. And when writing some Java, I miss Go’s use-site interfaces and TypeScript’s structural typing, while I miss nominal typing in TypeScript. It’s just maybe that you get used to workarounds and idiosyncrasies in some system and then carry them over to another paradigms.
I do like Go’s value propositions, and lots of its warts have been sorted out, but I’m just not as productive in it for my use cases as I am with Rust. It just checks way more boxes with me.
I love Go. It makes that I get shit done. I picked up Go more than ten years ago, because it was HN’s darling and when I didn’t know about hype cycles. No regrets.
41 comments
[ 6.2 ms ] story [ 67.4 ms ] threadgo is amazing. switches from python to go 7 years ago. It's the reason our startup did well
It took a few more years before I actually got around to learning it and I have to say I've never picked up a language so quickly. (Which makes sense, it's got the smallest language spec of any of them)
I'm sure there are plenty of reasons this is wrong, but it feels like Go gets me 80% of the way to Rust with 20% of the effort.
We shall not talk about compile time / resource usage differences ;)
I mean, Rust is nice, but compared to when i learned it like 10 years ago, it really looks a lot more these days, like it took too much of a que from C++.
While Go syntax is still the same as it was 10 years ago with barely anything new. What may anger people but even so...
The only thing i love to see is reduce executable sizes because pushing large executables on a dinky upload line, to remove testing is not fun.
Writing microservices at $DAYJOB feels far easier and less guess-work, even if it requires more upfront code, because it’s clear what each piece does and why.
Recently I made the same assertions as to Go's advantage for LLM/AI orchestration.
https://news.ycombinator.com/item?id=45895897
It would not surprise me that Google (being the massive services company that it is) would have sent an internal memo instructing teams not to use the Python tool chain to produce production agents or tooling and use Golang.
At work we use Uber’s NillAway, so that helps bit. https://github.com/uber-go/nilaway Though actually having the type system handle it would be nicer.
If I had a magic wand, the only things I would add is better nulability checks, add stack traces by default for errors, and exhaustive checks for sum types. Other than that, it does everything I want.
https://en.wikipedia.org/wiki/Go!_(programming_language)#Con...
The Go codebases look all alike. Not only the language has really few primitives but also the code conventions enforced by standard library, gofmt, and golangci-lint implies that the structure of code bases are very similar.
Many language communities can't even agree on the build tooling.
I would not use Golang for a big codebase with lots of business logic. Golang has not made a dent in Java usage at big companies, no large company is going to try replacing their Java codebases with Golang because there's no benefit, Java is almost as fast as Golang and has classes and actually has a richer set of concurrency primitives.
Go’s lack of inheritance is one of its bolder decisions and I think has been proven entirely correct in use.
Instead of the incidental complexity encouraged by pointless inheritance hierarchies we go back to structure which bundle data and behaviour and can compose them instead.
Favouring composition over inheritance is not a new idea nor did it come from the authors of Go.
Also the author of Java (Gosling) disagrees with you.
https://www.infoworld.com/article/2160788/why-extends-is-evi...
There may be no honor amongst thieves but there is honor amongst langdevs, and when they did Go! dirty, Google made clear which one they are.
Status changed to Unfortunate
https://github.com/golang/go/issues/9#issuecomment-66047478
Instead of “int x”
You have “var x int”
Which obscures the type, making it harder to read the code. The only justification is that 16 years ago, some guy thought he was being clever. For 99.99% of code, it’s a worse syntax. Nobody does eight levels of pointer redirection in typical everyday code.
I remember making a little web app and seeing the type errors pop up magically in all he right places where I missed things in my structs. It was a life-changing experience.
Proponents say it has nothing under the hood. I see under-the-hood-magic happen every time.
1) The arrays append is one example. Try removing an element from an array - you must rely on some magic and awkward syntax, and there's no clear explanation what actually happens under the hood (all docs just show you that a slice is a pointer to a piece of vector).
2) enums creation is just nonsense
3) To make matters worse, at work we have a linter that forbids merging a branch if you a) don't do if err != nil for every case b) have >20 for & if/else clauses. This makes you split functions in many pieces, turning your code into enterprise Java.
It feels like, to implement same things, Go is 2x slower than in Rust.
On the positive side,
* interfaces are simpler, without some stricter Rust's limitations; the only problem with them is that in the using code, you can't tell one from a struct
* it's really fast to pick up, I needed just couple of days to see examples and start coding stuff.
I think Go would have been great with
* proper enums (I'll be fine if they have no wrapped data)
* sensible arrays & slices, without any magic and awkward syntax
* iterators
* result unwrapping shorthands
From what I’ve experienced, if you need any fine-grained control over your data or allocations, precision on the type level, expressing nontrivial algorithms, Go is just too clumsy.
The more I read about how people use Go today and what issues people still have, the more I’m happy I picked Rust for almost everything. I even find it much more productive to write scripts in Rust than in Python or shell script. You just get it right very quickly and you don’t need to care about the idiosyncrasies of ancient tech debt that would otherwise creep into your new projects. And of course the outcome is way more maintainable.
Not saying that Rust hadn’t had its own warts, but most of them are made explicit. This is perhaps what I appreciate the most.
Intuitively, however, I still notice myself creating a new Python or shell script file when I need something quick, but then something doesn’t really work well the moment the logic gets a bit more complex, and I need to backtrack and refactor. With Rust, this hasn’t been an issue in my experience.
And intuitively, I still tend to think in Java terms when designing. It’s funny how it sticks for so long. And when writing some Java, I miss Go’s use-site interfaces and TypeScript’s structural typing, while I miss nominal typing in TypeScript. It’s just maybe that you get used to workarounds and idiosyncrasies in some system and then carry them over to another paradigms.
I do like Go’s value propositions, and lots of its warts have been sorted out, but I’m just not as productive in it for my use cases as I am with Rust. It just checks way more boxes with me.
It is so weird that they still claim this after they have made the the semantic change for 3-clause for-loop in Go 1.22.
When a Go module is upgraded from 1.21- to 1.22+, there are some potential breaking cases which are hard to detect in time. https://go101.org/blog/2024-03-01-for-loop-semantic-changes-...
Go toolchain 1.22 broke compatibility for sure. Even the core team admit it. https://go101.org/bugs/go-build-directive-not-work.html
Maybe by 18, or 21, the maturity finally settles in.