2016 was a golden year for Go.
Google’s very own open-source programming language was rated the most popular of the year in the TIOBE index. While it is yet to break into the top ten most-used languages, it saw the highest increase in popularity over the course of the year and continues to go for (gopher? No?) the major players; as February came to a close it was sitting pretty in 14th position. Not bad for a language that’s barely 8 years old.
Here at Bugfender we’ve been using Go for over a year now. "So what?" We hear you yell: "Why should I be listening to you?"
- We’ve got hands-on experience applying Go to real products.
- Our service is processing more than 50M logs per day.
- Our SDK is installed on over 9.5 million devices worldwide.
- We are handling more than 200GB of incoming data each day.
- We are not Google.
So we’re keen to share our experiences using Go. Only, we’re not in complete agreement over it.
In fact, two of our programming pros have gone head-to-head and have tunnelled through, gopher-style, the pros and cons of this prolific programming language.
Let the Battle Commence.
Aleix kicks things off by getting straight to the point: Go’s ease of use.
"The core language is very simple and similar to C/C++. You can pick up the basics quickly, especially if you’re already familiar with other languages. Perhaps you lose some of the functionality seen in other languages, but the simplicity allows for code to be easily understood by anyone reading it."
He’s also a fan of the concurrency features, in Go’s case exercised through its â€˜Goroutines’:
"If you have tried to do multithreading code using other languages you might already know how painful is it. Go is the easiest language I have ever used for running background coding tasks. Just write the code as usual and then add the go keyword on calling the function. That’s all there is to it!"
Jordi takes no issue with the ease of use, but notes that the developer talent pool is relatively shallow:
"Let’s say you started a project with Go in order to get to grips with the language, but that project matured into something much bigger. You need to hire some help. You’ve overcome the difficulty of learning a new language but you’re faced with an entirely new problem: finding someone proficient enough in Go that they don’t have to start learning from scratch like you did."
Virtual Machine and Dependencies
Aleix is feeling confident now, and moves onto dependency management:
"Your code is compiled to a binary that doesn’t need a virtual machine, so you don’t need to worry about any dependencies when deploying or distributing your app. As there’s no virtual machine involved to run your code, the app will use less resources than one that relies upon a virtual machine."
Jordi agrees that the feature itself is a plus:
"Admittedly, most programming languages do not have a dependency manager; the fact that Go has one is cool. It’s nice that dependencies can be expressed within the same files where the dependant code resides. No other tools apart from the Go toolkit need to be used to pull those dependencies."
So all smiles then? Well...
"It’s an issue, that you cannot indicate a specific version of the dependencies to use. This means that the latest version of the dependency will be used (the “master branch). This leads to all sorts of errors, like different contributors using different versions of the libraries, or code that used to work breaking because a dependency has been changed."
The current best-practice fix?
"Creating a local copy of all your dependencies. This is called “vendoring the workspace”. It leads to dozens of copies of the same files and is still a quite manual and error-prone process."
Aleix, reeling from a couple of Jordi jabs from the dependencies round, is still fighting-fit:
"Go enforces you to use a specific coding style, but it provides you with the tools to easily format your code by following the rules. No longer will you be left with a mish-mash of coding styles depending on who wrote the code."
Jordi counters by claiming the language can be rather opinionated:
"It’s a bit painful at times. You have to struggle with compiler errors that most programming language would consider warnings."
He throws in an example for good measure:
"Circular dependencies are not permitted. I know they’re a bad thing in software design. But it happens. You have two different sets of codes (in Go they’re called “packages”) that were not designed to be dependent on each other but at some point they have become so. Applying the generally-accepted best practice in software engineering, you should refactor your code to either remove this dependency or make it a single package (since one cannot exist without the other). In Go, this is not a best practice–it’s compulsory. And be prepared, because without a good IDE that can do the refactoring for you (we’re yet to find one), this can take several hours of your time."
Ouch. Can Aleix strike back?
"The program is strict with warnings, yes. You’ll be shown an error if a variable isn’t used in your code. But this only results in better code."
This tussle is spicing up. Let’s move on to the standard library. Aleix is a fan:
"The standard library has a wide range of built-in functionality that allows you to write code very fast."
Jordi jumps in:
"Go comes with something called “slices”, that are a slightly more convenient data structure backed by static arrays. If you want to use something more complex - store your data in a hashmap, treemap or a hashset for example, then you’re out of luck. There’s no provision for these things in the language."
Aleix senses his opportunity and pounces:
"As simplicity goes, Go is excellent. Want to encode/decode a json string? You can do it with a single line of code. Want to write a web server? There’s an http library than you can draw on. I could go on..."
Aleix is bouncing from one foot to the other; he’s feeling good and looking lively:
"Go is statically typed, so you avoid all the variable type problems that come with dynamic languages. It has a unique way of handling errors which forces the developer to think carefully over individual error cases. Last but not least, it has a garbage collector; there’s no need to worry about memory leaks or double freed variables like you would need to do in C/C++."
"There’s a glaring omission in Go that makes it less safe: generics. Every modern programming language has the notion of generic structures. C++ has featured support for generics for a while now. Go doesn’t.”“In Go you’ll have to resort to type checking and casts. This makes your code messy and unsafe. Go has not ruled out the future inclusion of generics but it’s yet to be implemented. In my opinion, this is yet another sign that the language is still too young."
But Aleix is back:
"If you’re worried about code quality and robustness, then start writing tests. Go makes it super simple to do so, simply create a new go file with the same name as the one you want to test and add the suffix â€˜_test’. Your code is tested and you can sleep with no worries."
Debugging and Profiling
Jordi has something to say about debugging:
"One of the other signs that Go is still a young platform is the lack of a solid debugger. Delve is, to our knowledge, the best one out there, but even their developers warn that it’s in a “pre 1.0 state in their documentation. Delve is a command-line utility, but it would be great to have it integrated in your IDE. We’ve got it running in Visual Studio code, where it occasionally fails. We’ve also tried it with IntelliJ IDEA, and it works, but could be greatly improved. If debugging is difficult, profiling is even trickier. We’ve never managed to get the profiler working in command line. We’re not aware of any IDE integration for it."
We’re coming into the final stages now. Both developers are looking weary; they’d like nothing better than to stick on a pair of headphones and zone out with a good coding session. But they’re still slugging away.
Here’s Aleix on documentation:
"When it comes to documenting your own code, Go really excels. There’s a standard way of documenting all of your functions and libraries, as well as using the right tools at the right time. You even get warnings when you write functions without documentation."
Jordi is far from defeated:
"GitHub contains lots of libraries that are half-baked, under heavy development (meaning the API will break often), or abandoned. One such example is gorm, the ORM we are using at Bugfender, which has been recently rewritten from scratch. Martini, which was one of the best when we started a year ago, has now been abandoned. Most StackOverflow questions are on basic topics: people figuring out how to use the Go toolkit, libraries not working, strange compilation errors and so on. The same goes for blog posts on Go coding."
Our developers are shattered, but satisfied. Breathing heavily, they start to drag their battered bodies back to their desks.
Aleix turns around, and gets one last word in:
"Are you still writing your code in PHP? Or even worse, C++? If you are, you’re old-school. Get with the program and start using Go–the hottest programming language in Silicon Valley. Everyone knows NodeJS. Learn Go and show the world you’re a hardcore developer!"
So, who should be declared the winner? Do you back Aleix, or are you with Jordi?
While we sometimes have different opinions on Go, we’re thrilled to be exploring what the language has to offer. If you have any feedback, we’d love to hear from you, especially if you’re an experienced Go developer!