Why I Love Programming in Go

Mal Curtis

I’ve been programming in Go for a couple of years now, and while it took a little warming to in the beginning, it has become my go to language of choice for its speed, reliability and overall productivity. I’ve used it in projects both big and small, and it has yet to let me down. I’ve picked a few of the things that make Go stand out for me, and that really sum up what makes Go a pleasure to code in.

Robust standard library

A lot of languages and their ecosystems have a level of “third party library” institutional knowledge. “Oh don’t use the built-in CSV parsers, use FastCSV”. “You’re using Thin? You should be using Unicorn”. “You’re using Node? IO.js is where it’s at”. This sort of fragmentation is generally due to a less-than-perfect implementation of standard library features, and creates a high barrier to entry for a language. The Go language is renowned for having a rock-solid Standard Library. More often than not, the standard library contains all you need to write your applications. For example, it has a built in ‘http’ stack that can serve your web applications without breaking a sweat – Google’s download service (dl.google.com) uses this library to serve up Chrome, Earth, Android SDK, and other large Google downloads.

Static typing

Coming from a dynamic scripting past (PHP and Ruby) I was initially wary of a statically typed language. After the first frustrations around updating function expectations and returns, I now fear going back to dynamic typing. The type checker is capable of picking up incorrect function names and type assignments. Because I no longer have to write tests to assert the error behaviour of my code when wrong types are supplied, nor check that a method name is even correct, my test suites are able to focus on the expected business logic, not these basic assertions.

Fast compilation

Not only is Go a fast language, but it’s optimised for compile time. In reality this means your Go binaries should compile in two or three seconds. This is a serious win for developer productivity. The ability to quickly switch between code and command line when writing applications is extremely important. If a compile takes significant time, it throws a developer out of their flow. Even 10 seconds is enough for your brain to switch off; you switch context and open Reddit or Hacker News, then sometime after the compilation is done you remember to go back and see the results. This constant context switching is not something humans are great at, and your overall productivity is not the best it can be. I’ve managed to avoid this in Go.

Simple concurrency

Adding concurrency to your Go applications is incredibly simple through the use of ‘goroutines’ to run code asynchronously and ‘channels’ to communicate. Go has a mantra that sums up the communication model:

Do not communicate by sharing memory; instead, share memory by communicating.

Channels provide a mechanism to both send and receive data. These channels ensure strict ordering, and provide a method for synchronizing concurrent code. By passing data across channels, rather than accessing shared variables, there’s no need for locking access to data, and tasks that can fail in complicated and unexpected ways in other languages are concisely written in small amounts of Go. You can also easily unlock the full power of the hardware your code runs on by running your goroutines across multiple cpu cores.

Official formatting

Go is very opinionated about formatting, and this may not be for some developers. The ‘gofmt’ tool that comes with Go will automatically format your code to follow the formatting standard. By hooking this tool into your editor’s save command you can ensure your files are formatted correctly. No more ‘fix whitespace’ or ‘New line here please’ comments during code review – you can focus on the things that matter, the business logic of your code. It still gives me a kick to see my code auto-formatted for me, and I have been trying to introduce tools to do this for me in other languages I work with ever since. Once you gofmt, you’ll never go back.

In yo’ face error handling

Error handling in Go is a first class citizen. You receive errors back from any function where an error condition could occur. Often these are the second value returned from a function, so this sort of code is very prevalent:

data, err := db.Query(“SELECT * FROM table”)
if err != nil {
	// Handle your error here, perhaps by returning it
	// from this function for the calling code to deal with

Having your errors as such an integral part of your code’s flow makes you think of what an error means for every particular piece of code you write. I can honestly say I’ve never thought about errors so much in my life, and this is a good thing. I now know exactly what the failure conditions of my code look like, and how they are handled. Because of this, Go code is robust code. Ignoring errors is a conscious decision, and very rarely done. While some might see this as verbose, or untidy, and it certainly does add some lines to your code, the payoff far outweighs the cost.

If any of these attributes have resonated with you, I encourage you to give Go a try. Learnable have just released my book “Level Up Your Web Applications with Go” which will take you from a complete Go novice, to writing Go Web Applications in no time.