Many people focus on some Go tech features making it attractive. Here I want to show you how it changed our org from a completely different perspective, increasing the performance and the quality of both our code and more importantly, our Team.
This is what we learned about team and code quality after 5 years of using Go.
First of all, we had issues, and we decided to address them. Then (5 years ago) the company was really small and mainly made by firmware developers coming from a C/C++ background, some Java devs, Backend developers using Python, PHP, and Node.js, some usage of CoffeeScript and other unpopular tools was also tolerated.
Choosing all the time the right tool for the job landed to inefficiencies in such a small company. Here is why switching between languages always has these issues:
- You need some time to understand them (from days to months)
- You need a different toolchain (usually waste at least 1 day to install all the stuff on your PC, IDE, compilers, etc.)
- If you hire a new junior member they have to learn several languages/tools before being productive
- Context Switching
- Very hard for other teams to make reviews of code written in a language they do not know
So we decided to cut out a lot of programming languages and we kept just a few of them.
Java, PHP, Coffeescript, Python, were all being converted with Go
C/C++ will still be there where Go cannot be used (read Microcontrollers)
Every new project has to start with Go if technically possible.
Go is a UX winner
Go was the language with less friction than others, our metrics were:
- Easy to understand by Junior Devs coming from the University
- Good overall performance
- One single binary to ship code, just copy it in a chat and everyone can run your code.
- Great tooling (IDE support, debuggers, etc.)
- Uniform formatting rules (go fmt)
- Understandable by both Web Developers and Firmware Developers
- Good to build network code
- Flexible from small to big projects
In one sentence: Go is a real winner in Ergonomy and UX
For us, technical features were just nice and useful for our use-case but what changed our org was a really good (and small) standard lib, the ecosystem of tools is of high quality, you are free to pick the libs you need and very comfortable in writing your own instead of importing huge ones.
Team and Knowledge Sharing
This was for us the most important feature of the language, it has been liked by incredibly experienced C++ developers, new developers were able to understand it, Backend developers loved it immediately. Developer of interpreted languages were surprised by some language features like Reflection or package management. System Administrators were able to deploy a single binary. If we wanted feedback from the Management, a binary sent via Slack was enough to let them test an application.
Everyone was able to read someone else code, in an orchestra, having everyone knowing the music score language is a big advantage, that was clear for us, small team benefit a lot by sharing language. Indeed we shared memory by communicating, as the Go pattern suggest.
How Go did improve our code quality?
Pretty easy too, we run go fmt everywhere, if you think this is obvious, it is, but I still look back at our legacy PHP code and the difference is incredible. There is no way to leave unused code in your app because it won’t compile (you cannot import something without using it). Is this annoying? Yes, the first week or so, then you will start enjoying the clarity of your code and get used to it, eventually almost hope to get that errors proving you can get rid of yet another dependency.
Compilation time is fast, really fast! It is as seamless as having an interpreter language but with the advantage of having a single binary to deploy. If you do not think this is a big improvement it is because you never had to fight with NPM before Docker was born, or with Maven or Python pip installation failing due to Python 2 to Python 3 transition.
It is also much better than C/C++ for our use cases, everything is statically linked, and yes, since version 1.5, you can also dynamically link libs (https://golang.org/cmd/link/ or more, in general, you can use gccgo or other tools). More info at Go Execution Model Docs written by the great researcher Ian Lance Taylor.
Testing includes a benchmarking tool built into the language, no need for external tools for basic performance testing, more interesting, the tests uses to be alongside the code, with a file named the same as the file to test with a _test suffix. If it sounds easy, is because it is easy.
The Go language is modern, is not modern in the sense to be disruptive, it is just more modern than the languages that inspired it.
You can mix Reflection and type safety depending on your needs. You can make it mimic an interpreted language and still being safe in most cases.
It scales, massively! It is because everything is designed around this simple but powerful concept
Do not communicate by sharing memory; instead, share memory by communicating.
This will not only allow what everyone knows about Go, concurrency but also will let you scale on multiple servers your application. It is very easy to add to your project a gRPC interface and keep the rest of the code as-is. We did that in the arduino-cli so now you can have an arduino-cli working remotely on a Raspberry Pi with some Arduino boards attached to it and control them from anywhere in the world.
Conferences and documentation
Go Conferences are great, very high quality, people are engaged and there are no fan-boys compared to a few other dev communities, most Go developers are scientists who are happy to see data confuting their thesis.
The vast majority of Go language is not in its technological ideas or features. It is in the actual implementation of those ideas with the User always in mind. The UX of the language was way ahead of many other compiled languages born before it. Go has contributed to the rise of other languages inspired by it, and we all should be grateful for this.