If you’re a Java dev, and you try to force Java-isms into Go, you’re gonna have a bad time.
The Go philosophy http://go-proverbs.github.io/ pays off less in the short term, within a single file, or a single stdlib function, or with syntactic sugar to code golf 3 lines into 1 - it pays off in the long term, across time and people - and this makes all the difference
I've found that often people who have been deep in the JVM ecosystem really struggle to enjoy Go, and vice versa.
It's like the JVM ecosystem commits deeply to the complete opposite of idiomatic Go, and once you've built those neural pathways, it's hard to unlearn it all.
I spent around 15 years doing Java exclusively, and after discovering Go (around 2012) I couldn't wait to adopt it and have never looked back since. I don't think Go is perfect, but I find it a much better default pick for most things I've worked on compared to Java. Of course Go has limitations, especially in the type system and error handling, but rather than go back to Java for those cases where it matters most to me, I tend to choose Rust these days. It shares some of the advantages of Java (compared to Go) and also comes with its own set of other major advantages too.
I hate Java just as much, but at least it’s trying to improve and grow beyond its past limitations, instead of promoting bad design decisions as good for the programmer.
I have worked with many languages - from Java, Delphi, C/C++, Assembly, PHP, Go, Rust etc. I don't really understand the hatred for Java. The build system in Java is not complicated .. whether Gradle, Maven or whatever unless your requirements are very complicated (multiple builds etc).
In my opinion the most complicated system out there is Javascript and all of the myriad tools needed to support that ecosystem. It has approached the complexity of C++ and perhaps even exceeded it
I'm a committed Kotlin shill and a very experienced Gradle user but I'm the first to admit that it is absolutely arcane for those new to it. Once you know all the incantations it's really flexible and performant but good luck writing a plugin for the first time.
Very interesting. Bulk of my career has been writing Kotlin/Java and after a year of Go I am _still_ really struggling. Nice to know I'm not alone!
I see the benefits (I've have seen some absolute Java ee monstrosities that would be impossible to build in Go) but why am I getting paged at 3am because someone forgot to set a field on a struct. Similarly all the codegen to workaround the lack of inheritance - who cares how fast the compiler is if you've got to do 30s of codegen on top.
Are you sure there such an entity as "the JVM ecosystem"? What is the common thread you can run through Kotlin Android jockeys, Clojure scientists, and Enterprise Fizzbuzz Java 11 types?
Yes who needs generics and a proper error handling system.
When you can have Go where the boilerplate is so bad you literally have to rely on generating source code files in order to maintain a sane level of productivity.
I use idiomatic Go every day and it's like being back in the 90s.
In our entire codebase, Go's generics have been used, like, 3 times, even though they were introduced almost 3 years ago. It's unsurprising: generics are most useful for writing your own custom containers, and generally, most projects don't need their own custom containers. It felt somewhat anticlimactic, considering all the anticipation.
I don't know about other people's experience, but from mine, I see a lot (most) devs abstracting too early in the name of clean code. I guess engineers gonna engineer when simple boring repetition is sufficient and those premature abstraction are unnecessary.
Yea lets build a whole docker setup for this little Sudoku app that never will have more than 100 users. I mean, for fun overengineering small projects can be a great learning experience but for work? Keep it simple, stupid.
(In case it wasn't clear, im agreeing with your point and just giving some example)
> lets build a whole docker setup for this little Sudoku app that never will have more than 100 users.
Looks good on the CV though and managers who hire-by-cv-not-sense love that kind of thing. You'd be amazed at how many interviews I've failed by pointing out that following the latest trends and over-engineering isn't always a good plan.
Also means there's a constant supply of work for contractors who can unpick that kind of gibberish back into reliable systems which is nice.
If I had a penny for every time I try to dissuade a dev from busing a huge k8s system for a business that does not have a single user yet - I would have a bunch of pennies
Yeah but what does simple mean? I struggle with that a lot. In my experience, keeping it simple means not being flexible when requirements change. Adding new features becomes tedious or even a mess. Keeping things simple is an art, certainly not an easy one.
Boring repetition is a bad fit for the human brain. Working memory is very small. Mistakes per line are frequent. It wants to see patterns that are not quite there. Even when it works out, it's millions of times slower than having the computer fill in grunt work from a more concise and readable spec of the problem.
Go is at a weird place where the standard library is big that third party libraries aren't really required but not that big that it can do everything. So like OP says there is a huge thing with Go projects (and devs) about reinventing the wheel for each project. While sometimes this is fine (and even welcome because it offers you flexibility and customization), it is mostly really slowing down someone who wants to write a full-featured application with auth/ORM/web security etc.
You either have to write your own or try to use something that is actually really behind from what you're used to. And coming from a Python, all batteries-included ecosystem it's actually nuts. Our small team would have to dedicate a huge chunk of dev cycles to write our own plumbing. Dev cycles that we could have used writing business logic that actually made us money instead of writing yet another auth.
But having said that, I don't think Go is the language to write these kinds of apps in. So if you're trying to use Go to do that, you're obviously going to run into roadblocks. It's like trying to cut through metal with a pair of gardening shears. Can it be done? Yes. Can I choose the size and design of the shears? Yes. Can I modify or create my own shears? Yes. But is it the most efficient or appropriate tool for the job? Probably not.
IMO Go is ideal for server/CLI applications or even for web apps that interact with other services completely behind your network. But for most other things you're better using something else. Or you use it if your customer really wants to use Go and wants to pay you.
Go is like a tool used to build the plumbing and internal systems of your house, but not the house itself. Using Go is similar to casting and forging your own water pipes. Some people enjoy getting into the details of crafting those pipes, but most of us just want to install them and focus on the rest of the construction.
> Go is like a tool used to build the plumbing and internal systems of your house, but not the house itself. Using Go is similar to casting and forging your own water pipes. Some people enjoy getting into the details of crafting those pipes, but most of us just want to install them and focus on the rest of the construction.
It actually gives me the house, it just doesn't do decoration. I hate doing decoration anyway. Other languages + their frameworks usually force me to care about that.
Plenty of people who love meat go to vegan restaurants, because they serve good food but without meat in the dishes. I have a bunch of language features I like but still use and enjoy languages that don’t have them because they’re still good at other things.
Go is kind of like a vegan restaurant that offers you iceberg lettuce and cherry tomatoes as the main course. It’s just not very good.
It's more like an aggro soylent of programming languages. It's functionally equivalent to other food intake products, but it will only ever have one flavor, and if you complain about it, they just tell you to drink more soylent because soylent is the One True Solution.
Now contrast that to rust, where rust is more "We know you like python, but did you know python and rust taste even better together?"
> The biggest challenges faced were most definitely not related to the choice of programming languages, but after cursing and fighting with Go’s mechanics and philosophy for years, I’m ready to throw in the towel.
I think that is the problem right there. Instead of cursing and fighting, you could have tried to understand, embrace, and adapt.
My opinion is that Go has the same problems as UNIX:
- Reactionary in the face of Multics' (resp. Java/C#) complexity, but overshooting to the point of "worse is better".
- Basically confusing "no complexity" with punting of said complexity to users who will solve it in multiple horrible and/or incompatible ways; like a badly designed R5RS Scheme.
- Some decent ideas but poorly and non-uniformly implemented compared to Plan 9 (whatever will fix Go).
Which is quite logical, knowing who made both of these...
I don't know enough about Java to comment on that switch (as modern Java seems to have gotten a lot of cool stuff like pattern matching and https://openjdk.org/jeps/485) BUT Java's runtime (which also powers Clojure and Scala) is evolving at an impressive rate compared to Go's: especially GraalVM and generational ZGC.
My personal experience of moving to using Go, along with building a small team using the language, all of us basically Java Devs, was that it was perfectly fine to go from Java to Go.
Code structure and package management were slightly sticky but getting a decent starting point on development was pretty trivial. Build, test and deploy were easy. A lot of style questions got answered by go fmt, vet and eventually golangci-lint.
I recognise some of the discussions but in all honesty we just tried to be consistent in our choices. Similarly, I recognise the complaint about dead 3rd party libs but I've seen that plenty in Java too, just some of the big hitters in Java are incredibly well maintained - Spring, Hibernate etc but in 20 years of Java I've been stung plenty by unmaintained libs too.
Go for us was quick to get started and proficient and whilst it's certainly not perfect a lot of the comment in the article appear to be more to do with team discussions than language choices. I've certainly had similar discussions on teams about Java and how to approach things.
Anyway, no longer in that team and now in one who's main language is Python, happy to use any of Python, Java or Go and for more than just system programming but really most sorts of problem spaces.
Of the 3 Go would be my default as it just works for me and love the build/test speed and even like the explicit error handling.
The Go philosophy http://go-proverbs.github.io/ pays off less in the short term, within a single file, or a single stdlib function, or with syntactic sugar to code golf 3 lines into 1 - it pays off in the long term, across time and people - and this makes all the difference
It's like the JVM ecosystem commits deeply to the complete opposite of idiomatic Go, and once you've built those neural pathways, it's hard to unlearn it all.
Kitchen sink stdlib, Exceptions, Verbose naming, Complex build system, @Deprecated...
In my opinion the most complicated system out there is Javascript and all of the myriad tools needed to support that ecosystem. It has approached the complexity of C++ and perhaps even exceeded it
I see the benefits (I've have seen some absolute Java ee monstrosities that would be impossible to build in Go) but why am I getting paged at 3am because someone forgot to set a field on a struct. Similarly all the codegen to workaround the lack of inheritance - who cares how fast the compiler is if you've got to do 30s of codegen on top.
https://golangci-lint.run/usage/linters/#exhaustruct
Java is my "main" language, but I do enjoy Go. I think it is very ergonomic, and it shines in some contexts where Java is lackluster.
The error handling in Go is kinda meh, but hardly a dealbreaker.
Now do drawbacks.
- Behold! The LongRangeAtomicStructureCompactinatingReconfigurator!
- (rolling eyes) So a ShrinkRay.
- No, no, it is named LongRangeAtomicStructureCompactinatingReconfigurator to improve readability and communication.
- (rolling eyes even more) Sure.
When you can have Go where the boilerplate is so bad you literally have to rely on generating source code files in order to maintain a sane level of productivity.
I use idiomatic Go every day and it's like being back in the 90s.
(In case it wasn't clear, im agreeing with your point and just giving some example)
Looks good on the CV though and managers who hire-by-cv-not-sense love that kind of thing. You'd be amazed at how many interviews I've failed by pointing out that following the latest trends and over-engineering isn't always a good plan.
Also means there's a constant supply of work for contractors who can unpick that kind of gibberish back into reliable systems which is nice.
Go is at a weird place where the standard library is big that third party libraries aren't really required but not that big that it can do everything. So like OP says there is a huge thing with Go projects (and devs) about reinventing the wheel for each project. While sometimes this is fine (and even welcome because it offers you flexibility and customization), it is mostly really slowing down someone who wants to write a full-featured application with auth/ORM/web security etc.
You either have to write your own or try to use something that is actually really behind from what you're used to. And coming from a Python, all batteries-included ecosystem it's actually nuts. Our small team would have to dedicate a huge chunk of dev cycles to write our own plumbing. Dev cycles that we could have used writing business logic that actually made us money instead of writing yet another auth.
But having said that, I don't think Go is the language to write these kinds of apps in. So if you're trying to use Go to do that, you're obviously going to run into roadblocks. It's like trying to cut through metal with a pair of gardening shears. Can it be done? Yes. Can I choose the size and design of the shears? Yes. Can I modify or create my own shears? Yes. But is it the most efficient or appropriate tool for the job? Probably not.
IMO Go is ideal for server/CLI applications or even for web apps that interact with other services completely behind your network. But for most other things you're better using something else. Or you use it if your customer really wants to use Go and wants to pay you.
Go is like a tool used to build the plumbing and internal systems of your house, but not the house itself. Using Go is similar to casting and forging your own water pipes. Some people enjoy getting into the details of crafting those pipes, but most of us just want to install them and focus on the rest of the construction.
It actually gives me the house, it just doesn't do decoration. I hate doing decoration anyway. Other languages + their frameworks usually force me to care about that.
Go is kind of like a vegan restaurant that offers you iceberg lettuce and cherry tomatoes as the main course. It’s just not very good.
Now contrast that to rust, where rust is more "We know you like python, but did you know python and rust taste even better together?"
I think that is the problem right there. Instead of cursing and fighting, you could have tried to understand, embrace, and adapt.
- Reactionary in the face of Multics' (resp. Java/C#) complexity, but overshooting to the point of "worse is better".
- Basically confusing "no complexity" with punting of said complexity to users who will solve it in multiple horrible and/or incompatible ways; like a badly designed R5RS Scheme.
- Some decent ideas but poorly and non-uniformly implemented compared to Plan 9 (whatever will fix Go).
Which is quite logical, knowing who made both of these...
I don't know enough about Java to comment on that switch (as modern Java seems to have gotten a lot of cool stuff like pattern matching and https://openjdk.org/jeps/485) BUT Java's runtime (which also powers Clojure and Scala) is evolving at an impressive rate compared to Go's: especially GraalVM and generational ZGC.
Code structure and package management were slightly sticky but getting a decent starting point on development was pretty trivial. Build, test and deploy were easy. A lot of style questions got answered by go fmt, vet and eventually golangci-lint.
I recognise some of the discussions but in all honesty we just tried to be consistent in our choices. Similarly, I recognise the complaint about dead 3rd party libs but I've seen that plenty in Java too, just some of the big hitters in Java are incredibly well maintained - Spring, Hibernate etc but in 20 years of Java I've been stung plenty by unmaintained libs too.
Go for us was quick to get started and proficient and whilst it's certainly not perfect a lot of the comment in the article appear to be more to do with team discussions than language choices. I've certainly had similar discussions on teams about Java and how to approach things.
Anyway, no longer in that team and now in one who's main language is Python, happy to use any of Python, Java or Go and for more than just system programming but really most sorts of problem spaces.
Of the 3 Go would be my default as it just works for me and love the build/test speed and even like the explicit error handling.
Some things are just marmite.