I really appreciate the simplicity, I think it totally makes sense at work where not everyone wants to deal with weird code. I think maintaining old golang code will not be a major problem in the future for example. The garbage collector make things a lot simpler too.
The dependencies management is not great compared to npm/crates/rubygems/... but it's still better than the Java world and it exists and it's being used.
I wish generics were already there, and I'm not a fan of the interface{} keyword. I'm also sick of the if err!=nil everywhere, I wish it could have a better error management like Haskell/Elm/Rust/...
I use Rust in my latest personal projet and while I prefer Rust, it's a bit too complex quite often and I spend more time thinking about rust things than thinking about the problem I'm solving.
This is not the case with Golang. It's not a fun programming language but it does most jobs very well.
Personally I don’t like it. Not low level enough for when I need to go low level, not high level enough when I want to go high level. Also I would have wanted generics right from the start; that should be the norm for typed languages unless the types are really super simple (Go’s are complex enough to warrant generics in my opinion).
But, maybe the reason why Go has the niche it has is because other programmers prefer it the way it so. So it goes with languages - it’s an aesthetics thing just as much as it is a technical thing.
The development process is fluid enough that I wish the language was suited to more usecases. When I need to handle complicated data (e.g. abstract syntax trees), I use Rust or Haskell because of their rich data types. But it tends to be much harder to get things running in those languages (borrow-checker and monads, respectively). I want to reach for Go to make those problems go away, but then realize that it would be really painful to try to express the program in Go. I understand that other people are unhappy with Go's development process, particularly if you deal with package versioning.
The language design itself may have been backed into a corner where adding generics will create an ugly mess (what will the standard library look like if it tries to maintain backwards compatibility?). Time will tell.
The tooling is mostly pretty good, but many things feel half-baked (compared to more mature ecosystems). On the spectrum of 'written in a weekend' to 'dozens of developer-years of work', the package "net/http/pprof" feels closer to the weekend side. There are bright sides, like having the production parser available as a library.
It's a language that is frustrating in different ways from other languages. Instead of fighting with Cabal/Stack, you have to write a million `if err != nil {}` statements. Part of what makes it frustrating is seeing how good it could have been.
My feelings after building for that long : safety and productivity.
I initially thought it was because of moving to compiler and type checking, but then I learned C for my personal use (an other thing passing through Go allowed for me), and was surprised to realize my C compiler was not allowing me close to the same peace of mind than my Go one. Go is just a well-designed language that makes everything straightforward.
The main reason I started learning and building with C is that I'm not confident the code I write in Go will age well. The discussions around Go-2 make me extremely nervous (it has something that reminds me of angular-2, python-3, symfony-2, bootstrap-3, and others major redesigns who left developers in a lot of troubles, I hope time will prove me incorrect).
So basically, I'm enjoying it, but I worry if it will last. I guess that means I really love it.
One of the things that might make it even better are generics, but I haven't really missed them so far. In conclusion, I don't think I will switch to anything else soon.
I do like it for small things - compiling to one (albeit huge) binary and its relative speediness is nice. I wouldn't use it for large systems though. The amount of code really balloons over time, relative to, say, python and that SLOC correlates to bugs and maintenance cost.
Checking that the user uses all values bound to variables but letting them discard errors by not binding them to a variable is a weird choice. Channels panicking instead of returning an error is a weird choice.
It's ok and I would like to to use it instead of Java.
99% of the time, trying to use idiomatic go instead of fighting the type system lets you have more maintainable and easier to understand code.
Now, every time i'm back to using another PL, i tend to rely on advanced type systems feature much less frequently, and only after making sure i'm not making the problem more complicated than it is.
We spend most of our work day reading and trying to understanding code. What you see is what you get with Go!
Side note: Go also runs fabulously on Kubernetes and is great for building micro-services :)
- Package management is terrible. - Development on Mac is not a great experience (someone in the team purchased a paid IDE, everyone else just run everything through a docker image, are we missing something obvious?). - The language is not flexible enough (lack of generics?) and code is significantly longer. - Lots of quirks.
I'm sure you can learn the language and overcome these small annoyances (and that's exactly what we did, because we wanted to squeeze more performance out of our services), but personally I think nowadays we have better languages which perform just as well (eg. Rust).
Regardless of the whole systems programming language polemic from the anti-GC crowd, several projects deployed into production like gVisor and TamaGo prove otherwise.
Finally thanks to killer applications like Docker, Kubernetes and everything around them, Go has become unavoidable for many developers, regardless of our opinion towards the language.
It's pretty crazy how used we are now to slow dynamic languages.
I also like how Hugo is available as a single binary file - much simpler compared to the complex build chain of a typical JavaScript app.
But if I'm trying to do a personal project, that amounts to a waste of time with 0 value.
My biggest gripe with the language is that it doesn't scale that well for teams. It requires a certain culture & approach to produce maintainable programs that goes against the grain for many developers, and while I enjoy the simplicity it offers, that simplicity leads to cost of ownership problems in many team scenarios. This con is mostly about the language.
As a specific tactical item, the runtime multiplexer could do with a refactor. The merging of the pollers essentially could continue until it is much cleaner, there are more layers there than necessary to solve the problem. You can follow the FD close path to understand the strains of the current factoring. Such a cleanup could probably remove some overhead for io heavy workloads too, maybe even drop some lock contention. Oh, and the spins should all be removed from the runtime before we really start using it on very high core count systems. This opportunity is mostly a side effect of a long history of incremental improvement.
It's good to get a lot of programmers onboard at Google who may have never written a line of C or C++ in their life. Coming from Java or Python, I can see the proposition of a language like Go. As in those languages, Go doesn't have myriad points of "unwritten code", e.g. having to worry about lifetimes of objects, the "rule of 5/6" for autogenerated methods (and knowing when the compiler generates some and not others) in C++. It's all there in the code with great verbosity.
I think people complain about Go because it's not the hammer for their nail. It's not for folks working with a team of moderate to elite-level C++ or Haskell folks who enjoy writing "beautiful code". It's for a company with an army of developers of varying degrees of skill who all have to maintain the same codebase without exploring the dark arts of the C++ abstract machine, and to do it in a much faster language than Java.
Like Java, it's driven primarily by business decisions for application software that needs to support all sorts of developers for server-side applications. It's very good at that. It's just that playing to that lowest common denominator creates an unpleasant experience for folks who want a more expressive language.
The golang standard library and high-quality third-party libraries are really great
If I had to choose between Go and C++, I'd probably pick Go because of C++'s complexity, so they really nailed it.
In the grand scheme of things, it's a really forgettable language. Frankly, I haven't programmed in it. I don't need to. I know ALGOL+(N+1) when I see it.
The tooling and ecosystem are ridiculous, the dependency management is a nightmare, and the fact it's backed by an incredibly evil company doesn't help either.
Further, any criticism of the language results in cult-like angry responses, as do most modern toy languages.
The reason it was adopted quickly was that building RESTful Web Services or gRPC Micro Services is relatively easy because all the libraries needed are native to the language. Of course I was building .net SOAP web services for years and knew the customers' needs. Another reason was the developers knew first hand how inflexible was configuring IIS with its web.config and the efforts needed to make it work.
Then the adoption of Kubernetes was easy too because it was written on Golang. The next transition to GCP was natural too. Basically being backed from Google made all this technology development and adoption a natural and I'm glad that I made this choice early.
Another reason I'm using Golang is that my recent project is mobile-GCP solution making possible to get information about 80mil/100GB US Property database in iOS App:
One of the reason this functionality was made possible because I managed to create Gomobile embedded database in iOS which is much faster than SQLite or CoreData for my purpose - creating geodetic solution - tapping on the map is retuning lat/lng which are two numbers and creating just one number representation of location suitable for key-value datastore.
I didn't like dealing with JSON data but other than that.. it's great to get work done in a simple way if work == services/backendy kind of things.
I would love to rewrite a lot of our python services in golang, both for the performance gains and to make the projects look more alike.
Python gives way too much flexibility, is a pain to deploy and has too many frameworks for doing the same thing.
Also, the dependency management.
Go-based software is smaller, faster, easier to deploy, easier to update, easier to contribute to.
I find that the installation footprint of a Go-based service is usually in the 10s of megabytes or less, where the installation footprint of pretty much anything else starts in the hundreds of megabytes.
In the classic world of one or two servers for a small company, sure, the disk space is meaningless, but with containerized workloads, small images are great for quick deploy, and quick iteration.
Credentials: I started using Go around 9 years ago and since then I've built a company of over 1,000 employees with ~250 engineers that write Go full time. We maintain dozens of open source projects and libraries (Terraform, Vault, etc. etc.) all written in Go. We've shipped commercial products that are used by a significant percentage of the F500. Vault for example serves trillions of secrets per year for _one_ company that we know of.
I could probably write pages and pages so I'll try to highlight a few things. Go is not a perfect language or community by any means but I love it.
NOTE: Folks often read this feedback with the opinion of "but language X can also..." or some variant and I hope that doesn't come across. My feedback is not against any other language unless I'm specifically using an example. Another language might solve all these same problems for you! I'm just sharing how Go has been fantastic at these aspects for us.
== Junior and new-hire friendliness
Go is a very simple language. From the beginning of the company until now, we can hire people who have never used Go, point them at a couple resources (i.e. Tour of Go), and they can be committing to production-grade projects within a week. It is incredible.
Go makes it really hard to do anything that isn't obvious. The cost of this is often verbosity or repetition. But the benefit above is well worth it in my opinion. I know lots of people disagree with this but I personally prefer to repeat "if err != nil" 1,000 times versus introducing new control flow options that now must be educated.
I love telling new folks (junior or not): read the file top to bottom, that's how it'll execute. And for the most part, that's true.
As someone who built a rapidly growing team/company around Go, this has been indispensable.
== Flexible
Any "general purpose language" can theoretically write any software. However, I'm sure we'll all agree that its easier to write some software in certain languages, and that's a good thing.
However, I've been blown away by how flexible Go has been without feeling forced. We've written desktop CLIs, web APIs, distributed systems, security software, networking software, infrastructure software, accounting software, bots, etc. all in Go.
And most of these categories are at a scale of millions of downloads per year and successfully in production.
It's very cool to see that coming from a prior major background in Ruby where there were significant tradeoffs when doing these things. It was _possible_ of course but you had to really understand the tradeoffs you were making. In Go, there's certainly some tradeoffs but they've been minimal and Go has just worked.
As both an individual contributor and manager, this flexibility has been awesome in building a company around.
== Cross-platform Compilation and Statically-Linked Binaries
Since the first day I adopted Go 9 years ago, Go has encouraged and simplified static binary compilation and simple cross-platform compilation. Today you basically set an env var of what platform you want to target, run `go build`, and it usually works.
You still have to learn of various gotchas around platforms (API availability, filepath awkwardness, subprocess/signal behavior, etc.) but the compilation aspect alone makes it so much easier to tackle this task.
My previous experience of at-scale software I built was Vagrant in Ruby, and making that work across platforms was a constant, enormous challenge. I had to spend a few months full time just to get installers to help setup the proper runtime environment across platforms.
Looking at this also from the perspective of rising popularity with ARM systems and other less standard architectures (even Power for enterprises...), this property of Go has been very important.
== Culture
The culture surrounding the Go community is generally one that is very philosophically aligned with how I view software. I would roughly describe it as pragmatic & measured.
I think this culture is exactly why many people dislike Go (or seem to "hate" it which I think is a pretty wild emotional reaction to a language for programming computers but I digress).
The Go community doesn't chase the next hot thing or rush to implement the "state-of-the-art" without a very measured, pragmatic approach. Some view this as Go being inferior by some definition but I view it as a huge benefit. Go core in particular appears to me (I'm not part of the core team so purely an opinion) to be a measure-twice-cut-once (or maybe measure like 8 times) approach. And I love that.
== Fun
At the end of the day, the language is generally fun for me. I like writing it. And that's important, too.
== Conclusion
I'm very lucky that Go took off as a language in the industry I built my company in. It certainly wasn't that way when we started using it (it was pre-1.0, pre-Docker, pre-K8S, the majority of infra sw was still in Ruby).
I feel that the language is super productive (we built Vault 0.1 in ~6 weeks for example), it has shown to scale to the largest needs and does so stably (Vault is in the hot path of every trade in one of the major US stock exchanges and has never gone down there), and we've been able to build a large company and active OSS community around it.
Hands down a successful choice for us with zero regrets.
- Type system sucks
- No decent package management system or dependency system
- No generics
- error handling is horrible.
... My fav lang right now is Typescript... You can do frontend stuff, backend stuff (with node). Great tool support, etc.
This is the biggest pain point of Go throughout my journey and I have been waiting so long for Go 2! PLEASE!
The tooling is also very good, though I wish more of golangci lint would move into stdlib so I could just run golint.
I've switched most of my personal projects over to Rust and so far I'm not looking back...
1. Built in support for tooling, testing, formatting etc
2. Trying to make concurrency mainstream
3. Large and developer friendly standard library, there is hardly any programming language where web backed can be written without using a framework or a library. Go is one of those.
My favorite feature is its simplicity. It imposes very little cognitive load, allowing you to spend more time thinking about the problem you are trying to solve and less time on language gymnastics. I am way “over” being impressed with that kind of cleverness. I am much more impressed with what a program does than with cleverness at the code level.
Go mostly picks the right features and avoids those that just add complexity, and it mostly gets that right.
It doesn’t get everything right. I am disappointed with channels and I do think it needs generics, though I hope the latter do not add much complexity and are not overused.
Tooling could use a lot of work though. After switching between vim-go, gopls, and a handful of other language server implementations, I've given up on auto-completion, definitions etc altogether. Maybe it's my setup...
Overall, I'm pretty happy with running a fairly big Go app in production. Would I choose Go for my next serious project? Most likely.
1. Tooling and library ecosystem of Java is still better. There are tools for pretty much everything, including high-quality commercial offerings. For example, IDEs, profilers, build systems, other languages that run on the same VM. Nearly every major SaaS I have ever integrated with has a Java SDK.
2. Weight of big players behind the ecosystem. Big companies all over the world are heavily invested in Java. Even Google is still more invested in Java than Go (internally, and in Android, especially). This makes Java an insanely safe choice for us small players.
3. The many, many warts and deficiencies of Java (and parts of the Java ecosystem) are well-known. Experienced developers, at least ones with good taste, know how to mitigate them without pain. For us, a language with fewer warts, like Golang, is therefore not as big of a selling point. It's like getting your hands dirty. When your hands are clean, you are reluctant to make them dirty. When your hands are already dirty, touching dirty things is not a big deal.
4. Golang is not the only language evolving. Rapid improvements to the language and JVM are already here, and more, bigger changes are planned (e.g. Loom, Valhalla) that will nullify some of Go's advantages.
* useful, not shiny. No new framework every year, just for the sake of it. An actually readable spec. Changes heavily thought through before being introduced. A programming language isn't a place to move fast and break things, as changes often cannot be undone.
* Readable code. You can figure out what a piece of code does pretty easily. Even if you can't do so at first glance, you know where to look next.
* Simplicity. I personally like having full understanding of things. This applies both to the language itself, as well as to the tools (go test, go mod, go generate etc). This is pretty subjective.
* The formatter. As a screen reader user, aligning things with spaces so that they would form nice little tables is a hard task for me. I'm happy I don't have to do so.
* Compiling programs as single, static binaries, assets included.
Some small things I don't like (also in that order):
* No try macro[1]. IMO try was a better solution than exceptions, and I found the arguments against it not that compelling.
* Overrelliance on struct tags, which shouldn't exist at all IMO. I don't want to couple my business logic, storage and view layers. Options for i.e. JSON should be specifiable at call time.
* No generics, or, even better, zig-like comptimes. They're simpler and more powerful, though they wouldn't probably neatly fit into go2.
Overall, I'd give go about 8.5/10.
[1] https://github.com/golang/proposal/blob/master/design/32437-...
It's basically the only language in meaningful use that optimizes for the right things in this context: productivity at the team scale (rather than the individual scale) and making things easier for code readers (rather than code authors).
* Refactoring is powerful
==========
Nobody can design well upfront for a large project. Constant refactoring is need for large projects. Go is super good on this.
* Generics is not ready yet.
==========
The distributed computation project was re-written multiple times. I tried different approaches to address the generics problem. I even tried to make it work fairly well with LuaJIT, but still decide to change again due to the need to learn a different scripting language and losing the type checking.
There are other "sexier" languages that I sometimes enjoy even more (Elixir, Rust), but Go is rock solid, easy to use, and has never let me down in production.
In my eyes, Go is also the modern times successor to the Wirth family of programming languages. In Europe, for a long time the Wirth languages were far more popular than C was. Only in this millenium they faded from public perception, but with Go many of their concepts and philosphies come back, even when dressed up like a C language :).
- great community
- ample libraries
- ecosystem support
- no breaking changes (yet)
- no magic, limited and simple
- inbuilt testing/profiling/dependency manager
In July 2018, I decided to go all-in on Golang. I like how fast it is, I like that it forces me to pay attention to my types. I wish that error handling felt less like yak shaving, but I understand the rationale. I write task-oriented servers/daemons, and CLI tools mostly, and it's great because it compiles down into a single binary with zero dependencies (which none of my other languages can claim), and it's extremely fast. It compiles easily for a variety of OS/Arch combinations, and as someone who can follow instructions to compile C/C++ code, dependency management is FAR easier than having to track down which "dev" versions of packages I need to install from whatever flavor of Linux or on macOS (via Homebrew). Overall, it's the best of many worlds for producing something that's easy for other people to consume.
These days, I do a lot with AWS, Docker, Security, Terraform, etc. I'm also going back to my web roots a bit on the weekends and looking at building a GraphQL API on top of DGraph, and the tooling for Go is really good. Lots of static analysis and linting tools are available to help me write the best code I can, and teach me when I've done something poorly.
My only big complaint is when I'm parsing JSON of which I don't know the shape. I end up with this nested mess of `map[string]interface{}` types that I have to sift and cast over. Even when I know the shape ahead of time, I still need to do the work to model it as a struct before I can work with it sanely. This is something that JS, PHP, Python, and Ruby all do with far more ease.
I still write in multiple languages frequently, but Go has become my go-to for a lot of things over the past couple of years.
I am far more interested in cutting edge languages such as Rust (borrow checker) or Idris (dependent types) or even C++ 20 (template madness), since these will allow me to express things that I cannot express in other languages. What does Go bring to the table?
Note that my perspective is of someone who works in a small team of experienced programmers, not a large organisation with more junior ones.
That said, Go is fun to work in, and is great for constructing microservices that are truly "micro" in terms of small footprint of code and dependencies. Today, enterprise development shops that embrace the microservice pattern hew stickler-like to the "do one thing" bit of Unix philosophy, but slack off on the "do it well" bit, bringing in dozens of dependencies to serve, say, a list of employee names and IDs out of a table. Go's opinionated minimalism helps to mitigate this trend, but Go has also proven itself up to large-ish development tasks like Kubernetes as well.
So that's Go -- capable, but not ideal. A worthy choice if you want to get something out there without fighting the borrow checker -- though you may wish to consider that time spent satisfying rustc now is more than paid for by maintenance time saved later.
I got too caught up in designing elaborate abstractions in those languages. I couldn't avoid it either, since other libraries would also use elaborate abstractions.
With Go, I just write plain dull code, against a suite of good dull libraries. Ultimately I spend less time writing programs (typically internet services) in Go than other languages.
Downside is no generics but otherwise great.
Just this week i wrote an entire toolchain for developing with an embed device, that now i can distribute to anyone that need to work on that project.
Before go i used nodejs/python due to the large ecosystem of library, but go nowadays has a similar ecosystem and allow me to build static executable without any dependency. That is super useful since i work with different OS (ubuntu, fedora, windows and macos). Also even sloppy/draft code is really fast and i don't need to start optimizing and profiling from the start like in python (i often process large dataset).
Lastly the language is very simple and my colleague who ,didn't even know go, learned in a week and, most importantly, is able to navigate my large codebase without much help (that for me is the biggest advantage of go)
With every other language, you checkout the code in any directory you want (as long as there are no spaces in the path), run either a language-specific tool or the traditional configure/make combo to compile and optionally install, and you're done. With Go, not only you had to put the code in a specific place in your home directory, but also every code written in Go you'd ever want to compile had to also be placed in that specific directory in a specific way, mixed with the code of other projects, instead of allowing you to place them separately in your personal projects directory hierarchy (which you already use with every other programming language).
- It's fast - given I work with PHP for a living it's no fair comparison really, transposing a processor-intensive algorithm into Go is like lifting a veil. In one instance I think Go ended up being ~100 times faster, and that was without splitting computation across multiple cores.
- Getting async multi-core concurrency feels smooth with golang, it's not that much of a stretch to transfer concepts from my experiences with async JavaScript / nodejs applications, only that it feels more natural dealing with flow control, race conditions, and shared resources in Go - JS tools have improved in recent years but being single threaded they only really approximate the experience of concurrency in Go and that can sometimes bite hard.
- It's fairly intuitive to pick up and use. I used to be a big fan of C#'s syntax, and prior to working with PHP I learned development with C-style languages (including C/C++) so anything with a similar syntax feels natural to me. Golang feels to me like JavaScript got in bed with C# and made a baby.
tl;dr: I'd definitely welcome the opportunity for some professional work using Go, and will certainly consider implementing some of my future projects with it to gain experience.
What I like about Go:
- explicit error handling, one is forced to write correct code and think how exactly the errors will be handled. I now prefer Go's approach over exceptions.
- code is readable, I can look at the code of my coworker and very quickly see what exactly it does.
- surprisingly, I found myself not missing OOP features
- If project is compilable on localhost, it will be compilable on the server... this is easy to achieve and also deployment is straightforward.
- it forces to write "stupidly simple" code. for example, it doesn't allow function parameters with default values. The consequence is, that I sometimes need to spend a little extra time on refactoring, but then have more readable code.
seqA = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
seqB = [2, 4, 6, 7, 11, 12, 14, 16, 17, 19, 20]
You could argue that seqA is simpler because it follows a regular pattern: the range of ints from 0 to 20, inclusive. Or you could argue that seqB is simpler because it contains fewer numbers.Go seems like seqB to me. It is simple in that it provides a limited set of features, but to me it ends up feeling fractured.
The only thing I dislike is the CSP concurrency paradigm the community and language try to push. Every time you ask someone how to implement something more complex using locks or atomics, they just parrot the "share memory by communicating" lemma.
i like: being able to cross-compile things into a single binary. raw speed in case of simple services
i dislike: the way generics and package management were (are handled/ignored?) and the super-verbose error handling.
go would not be my first choice but i can understand why people find it appealing
But the simplicity of the toolchain and breadth of the standard library makes it the most pragmatic major language for backends.
I think the backward compatibility has been the number one feature for me followed by the tooling and batteries included standard library.
It is nice to be able to do most things without depending on a 3rd party library.
I can usually understand everything happening in Go with a single pass without jumping around too much in the code.
Generics are the most contentious issue, and people have been disparaging Go since day 1 for not supporting them. And yet, somehow we've spent the last 10 years writing all kinds of programs in Go, and the lack of generics has rarely been a showstopper. Go does have generics of course -- it just doesn't have user-defined generics. My hot take is that this is actually an area of the programming space that deserves more exploration. It feels like a Pareto phenomenon, where adding a small number of generic types and functions covers 80% of the usecases. And indeed, it seems that generic arrays/slices/maps/channels, plus a generic 'append' function, a generic 'range' keyword, etc. really are sufficient for the vast majority of programming tasks. These "reified" generics have significant advantages: for one, you can build deep compiler optimizations and tooling around them; and for two, perhaps more importantly, every Go developer is familiar with them. Reducing mental overhead when reading someone else's code is a big part of the Go philosophy. (Having a really high-quality standard library contributes to this as well, for obvious reasons.)
People made similar arguments about operator overloading. It's true, operator overloading allows for more "expressive" code. It also allows people to write code that is much harder to read, harder to debug, and whose performance is harder to analyze. I think it could be cool to have an 'expressive {}' block, like Rust's 'unsafe {}', where overloading is allowed; but when I'm reading normal code, I don't want to have to worry about 'x + y' jumping away to some other piece of code.
(As a side note, I see many people arguing for generics based on their desire to write map/filter/reduce functions in Go. My feeling is that map/filter/reduce (and other HOFs) are unlikely to become commonplace in Go code, even if generics are added. The reason is lambda syntax: even the simplest map or filter will require three lines of code (or one long one), including multiple type definitions and a return statement. It's not enough of an improvement over a 'for' loop to be worth it. If you could write 'xs.map(x => x*x)', it'd be another story, but that would require a much deeper language change.)
Anyway, Go wasn't designed by idiots, which means you should apply Chesterton's Fence. If some aspects of the design seems wrong, or violates your sensibilities, your first instinct should be "perhaps this is optimizing for some usecase I haven't considered," or "perhaps this is targeting a particular niche that I'm not familiar with," rather than "this is clearly a mistake." The steelman argument, then, should be usually be of the form "It seems like Go is optimizing for X, but it falls short of X in significant ways," or "Go is targeting X, but doing so comprises value Y that I consider more important."
I’ve always loved playing with languages, so over the same period of time Rust was a language I’d often tinker with. It never really felt great for web stuff, but I kept going back to it to toy around with maybe a CLI here and there.
Fast forward to the pandemic and I found myself with a lot more free time at home, coupled with a newly mature async story in Rust, and everything changed for me. The error handling due to algebraic types is phenomenal (particularly with the ‘anyhow’ and ‘thiserror’ crates), rust-analyzer in my emacs is awesome, type safe SQL with sqlx is amazing, cargo is great, compiler error messages are super clear, and the list goes on.
I just started a new project with a client and the backend is written in Go, and honestly it’s a bit of a let down having to go back to it. It’s totally fine, it just doesn’t feel beautiful to me. Seeing empty interfaces with type casting makes me cringe (I mean it always has) and I’m really going to miss the Rust error handling. Thankfully a lot of this project I’m going to be able to use AWS lambda for and I’ll just use TypeScript since the front end team is using it there (no one is comfortable with Rust).
tldr; Go is a simple language that will let a team get things done and it’s easy enough for any developer to onboard with it. But personally I wouldn’t reach for it ever again because of Rust (and even TypeScript).
Second, the way imports work is obviously due to some internal google kitschy-ness. Remote import paths are so dumb. People set up entire domains and CDN's just to host some code. The import path has to have a specific format, you can't have three levels. github.com/me/sub1/module won't work, so everyone creates mypersonalgithub.com/sub1/module. It feels like one L3 at google set this up on a Friday, and the industry has to live with it. Of course all this code will be broken in 3 years.
There is no easy way to point imports to a local development copy of a repo because google uses a monorepo and everyone else has to live with it.
It's ok for writing small tools or simplistic web servers. For complex non-trivial applications, it is very poor at modeling, which introduces a lot of friction when dealing with larger code bases. Performance is adequate and nothing to brag about (it sacrifices throughput for latency) and compiling speed took a hit when they rewrote the compiler from C to golang. Linking times are quite abysmal for larger projects.
Depending on what you want to do, there are superior alternatives. Java and C# are both better in almost every aspect (and keep closing the gap when it comes to low latency and small footprint), and Rust is also a potential viable option if you are running in a memory constrained environment.