Go (also known as Golang) is awesome!
Let me explain why a Python fan of many years would think that—especially with the competition between Python and other programming languages being as fierce as it is.
In the process, you’ll learn which of the two languages will be the right fit for your project. Or perhaps there’s a third way that will give you the best of both worlds?
To show you what I mean, we’ll take a little trip down memory lane and explore how my fascination with Python began.
Let’s go back to the year 2002, when most people were using 56 kbps modems to chat on AIM or Gadu-Gadu and download MP3s from Kazaa or eMule. I had just started studying computer science and I saw Linux for the first time.
I was amazed like a child in a candy shop. You could do so much more in Linux than in the old Windows 98 that I had at that time. So I wanted to install it on my own computer at home.
I used my pocket money to buy Linux Magazine with Red Hat 7.3 installation CD. Imagine my disappointment when in the middle of the installation, the CD drive started to slow down and finally stopped.
That was when I saw Python traceback for the first time. I think it was an IOError because the CD was corrupted and couldn’t load some file.
I was sad. I tried to install it again and again. Every time the same exception popped up.
A broken feature in open-source software… it’s not a problem, it’s a challenge :)
Fortunately, Python traceback shows filenames and line numbers. So I could easily find where the error was in the source code of Anaconda, Red Hat’s installer written in Python.
When I opened the .py file, I was surprised that I could read it. I could even understand it without ever having read a tutorial of Python. At that time I was only able to program in C++ and Pascal, but learning those had taken a lot of hard work on my part.
To finish the story I have to boast that I modified the installer to omit corrupted files and I finally could use Linux at home. Python’s readability and flexibility impressed me so much that on that day, I became a Python fan for life.
A few months ago, I moved to another city to open a new STX Next office. In my newly rented flat in Gdansk, I don’t have a smart TV anymore. It’s not that bad because Kodi, a free and open-source media player running on my Raspberry Pi 3, is a very good replacement.
Unfortunately, the Link TV and Phone feature is missing in Kodi’s YouTube add-on. (If you haven’t used this feature yet I would definitely recommend to try it.)
A missing feature in open-source software… it’s not a problem, it’s a challenge!
I had heard that Kodi’s add-ons are written in Python, so I thought it would be easy. The process of pairing the TV and phone is quite easy and well documented (DIAL protocol) and there are even Python implementations (e.g. xbmc-dial).
But the exchange of commands between paired devices is not a piece of cake. Surprisingly, Google didn’t publish any documentation.
After a long search, I finally found plaincast, a tool written in Go that plays only the sound from YouTube videos. When I opened the .go file I was surprised that I could read it. More importantly, I could understand it without even reading a tutorial of Go.
So I took it as a base and I’ve created kodicast, a standalone service that sits in-between YouTube and Kodi. As you can see in the commit history, it only took me approximately 24 hours in total.
That’s not bad, especially if you consider I had to familiarize myself with two different protocols and make changes in a program written in a language I had only heard of.
My story notwithstanding, let’s get down to the business of comparing Python and Go.
First, let’s focus on performance as it’s usually understood: performance at runtime. Which language runs faster?
There’s no two ways to say this: Go runs faster than Python, in some use cases even 30 times faster.
In computer language benchmarks, Go finishes the mandelbrot
test 48x faster, spectral-norm
43x faster, and n-body
38x faster.
Golang’s built-in support for concurrency also helps it finish calculations faster compared to Python.
But for many use cases, runtime performance may not matter that much because very often the language is just the glue between the app and the database.
Which brings us to another way to think about performance.
Runtime performance may be important for some apps, but there's another metric that applies to any software project: your developers’ productivity.
Ultimately, you want to meet your project deadlines and get your code live where it can benefit end users. For most apps, this will be more important than whether some function executes within 10 ms or 100 ms.
So which development team will get faster results, one working with Python or one working with Go?
The obvious answer is “it depends,” but let’s have a closer look at which aspects of Python and Go will influence the results.
Python is well-known for its rich selection of frameworks and tons of useful libraries, helping developers get any project off the ground much faster.
From “batteries included” offerings like Django to more “minimalist but expandable” frameworks like Flask, Python will give your dev teams a running start in almost any situation.
It gets even better when you look at Python’s legendary roster of libraries:
Being a younger language, Golang hasn’t had the time to accumulate such an impressive offering of pre-built solutions yet.
But that’s not to say that Golang doesn't have anything to offer. Here are a few examples of Golang frameworks:
On stream.io’s blog, Thierry Schellenbach mentions why Stream made the switch from Python to Go. One of the reasons was that Go offers a certain simplicity, it doesn’t let you get so “creative” with the code you’re writing.
In Python, the case is rather the opposite. For example, with Python you can:
The question is: do you need these advanced features to deliver functional code?
In most cases, you don’t. And that’s to Golang’s advantage.
Go developers keep it simple—they almost have no other choice—so their code will be easier to understand when it changes hands. And when programmers can understand each other’s work at a glance, they can make changes faster, and productivity rises.
In terms of syntax, structure, and philosophy, here’s the shortest way to compare Python and Go:
There are some similarities between Go and Python. You can find some resemblance between high-level types—slices and maps are like lists and dicts, but with static typing. Go’s range works as Python’s enumerate. And that’s it.
The differences between the two languages are much more numerous. Some of them can be shocking for a Python developer. For example, in Go there is no try-except. Instead, Go allows functions to return an error type in addition to a result.
// getUUID returns a stable UUID based on the first MAC address
func getUUID() (*uuid.UUID, error) {
itfs, err := net.Interfaces()
if err != nil {
return nil, err
}
// get the first interface with a MAC address
for _, itf := range itfs {
if len(itf.HardwareAddr) == 0 {
continue
}
id := []byte(itf.HardwareAddr.String() + "-" + NAME)
return uuid.NewV5(uuid.NamespaceOID, id)
}
return nil, errors.New("could not find interface with MAC address")
}
So, when using a function, you first have to check if an error was returned or not.
deviceUUID, err := getUUID() if err != nil { logger.Fatal(err) }
Static typing is another thing that you have to get used to. Of course there are situations when you can’t be completely sure of the data type. For such situations, Go offers an empty interface (interface{}). It may hold values of any type, but when you want to use it (e.g. make some operations on it) you have to use type assertion to get the underlying value.
As an example, let’s look at parsing of some JSON data.
func (kodi *Kodi) getPlayerId() (int) {
resp, err := kodi.sendCommand("Player.GetActivePlayers", nil)
if err != nil {
return -1
}
// resp is a JSON [{"type":"video","playerid":0}]
result := resp.([]interface{})
for _, i := range result {
// a map with string keys but values can be a string or a number
// so we have to use empty interface as a value type
item := i.(map[string]interface{})
playerType := item["type"].(string)
if playerType == "video" {
return int(item["playerid"].(float64))
}
}
return -1
}
There are a few more Go novelties that Python developers will have to learn, such as:
So why can Python developers understand Go so easily? I think it’s because Go’s design follows similar principles.
Let’s compare the Go guiding principles and the Zen of Python. In both languages reducing clutter and complexity is a priority.
Go’s clean syntax rule leads to high readability, which is so valued by Pythonistas (Readability counts in the Zen of Python). Also, Go’s orthogonality, a trend to keep a relatively small set of basic building blocks, favors simplicity over complexity (Simple is better than complex). Static typing is consistent with the rule of explicitness as well (Explicit is better than implicit).
Finally, let’s take a look at what the future may hold for the two languages. It looks to be bright for both.
In the first quarter of 2019, Python was the #2 fastest programming language on GitHub in terms of pull requests (+17%), but Golang was hot on its heels at #4 (+8%).
The results of a recent survey published on the Go blog also provide insights into Golang’s growth:
Why is Python growing? The reasons are widely known:
And why is Golang on the rise? Maybe it’s because:
However, there’s still a significant chasm in terms of popularity between the two languages. Just take a look at Google Trends from the past 5 years:
All in all, both languages are on the rise and both would make a productive choice for your software project, albeit in different ways. Python remains the more mature option with a better selection of libraries and frameworks, but Go offers enticing performance and simplicity.
Many CTOs and software architects have to choose a programming language when they start a new project or create a startup. Python is very good for the web and data science. However, Go is much faster in terms of performance than any interpreted language such as Python.
To quote Happysad, my favorite band, “Never make me choose, because I may make a bad choice.” In this case, I think you don’t have to choose.
In my opinion using both Python and Go would be a powerful mix. You could use Go to write the code for which performance is critical, then use Python for the rest. A microservices architecture or even a serverless approach is probably the best way of mixing Go and Python together.
The similar design principles of Go and Python make the transition from Python to Go quite enjoyable. I hope to see more projects that mix Python and Go.
So, if you’re a Python Ranger—why not give Go a go?
Alternatively, you can also learn how Python compares to Node.js or Java.