A look back at the beginning of Go programming language
In November 2020, Go, the programming language, celebrated it’s eleventh birthday. Though Go has come a long way since it’s inception, compared to its peers, it is still considered as a newcomer in many circles. This article is an attempt to look back and recollect how the journey of Go began and provide a quick glance towards its design goals and a few features. Later, we’ll explore Go deeper in the articles that would follow.
This article is intended for those who are relatively new to Go programming language. If you are already familiar with Go, well, this could be a journey down the memory lane. :-)
The Origin Story
The story of Go began during second half of 2007 at Google. Three gentlemen from Google - Robert Griesemer, Rob Pike, and Ken Thompson - were trying to tackle some of the engineering challenges they faced. Google, due to it’s scale of operations, faces engineering challenges unlike many other organizations. Selection criteria for the trio to identify which programming language to use centred around three main considerations: efficient compilation, efficient execution and ease of programming.
Though they evaluated many of the existing languages, they couldn’t find any language which offered all three of their primary considerations. That realization led them to think about creating a new programming language. Thus, the seeds to develop Go were planted.
The design began in September 2007 as a 20% project at Google. As things progressed, many others joined as well. In January 2008, work on initial compiler started. The language was open-sourced later in November 2009. It took a few more years to release first stable version Go, in March 2012. Thus, the story of Go started and continues ever since.
Can a programming language exist without a mascot these days? That’ll be a bit lame, isn’t it? No worries, that’s covered as well. Go has a mascot too, called Gopher. Interestingly, initial version of the mascot was created by Renee French long before Go was born. The mascot was later adapted for the Go project. More details on the evolution of Go Gopher can be found here. It is an interesting read in itself.
Go or Golang?
You may have heard Go being referred as Golang as well. To set the record straight, official name of the language is Go (not Golang). You may wonder: If that’s the case, why is it sometimes called Golang? Well, when it was time to register a domain name for Go, the creators had challenges in getting domain names with just go. Thus, golang.org was chosen which led many folks to call the language as Golang too.
(At the time of initial draft of this writing, go dot org was available for sale for a brief time. What would be a worthy offer? “ a price in the lower seven-figure range”).
When Go was in the design phase, it’s designers had a few goals in mind. These goals were identified based on what they were trying to achieve and learning from drawbacks they saw in the other languages evaluated.
First and foremost, a simple language with clean, concise syntax was the target. Keeping keywords to a minimum was one of the means to achieve the same. A lightweight type system, with no type hierarchy, was desired in order to reduce complexity. Implicit conversions were purposefully kept out. It was felt that a strict separation between interface and implementation would keep things more simple. Composition over inheritance was another preference.
Support for large scale programming was one of the main objectives. This had two aspects:
System scale : Greater support for concurrency was a must have and an efficient process level communication mechanism was desired along with speed of compilation.
Engineering scale: The objective was to develop a language for large codebases that are written and maintained by big teams.
Support for modern hardware
Many of the languages available at that time - C/C++, Java, Python etc. - were designed prior to the existence of modern hardware. (Modern hardware, in this context, means multi-core CPUs, networked hardware & distributed systems.). Go was specifically designed to take advantage of the modern hardware.
Type-safety: Nobody likes type issues to pop up at runtime in Production environment. So, being type-safe was important.
Memory-safety: Nobody likes memory issues either. So, the ability to handle memory in a safe way mattered too.
A run-time environment with efficient, latency-free garbage collection was the target. In addition to that, they wanted to have built-in strings, maps and, communication channels for intra-thread communication.
Better Package model
A good package model goes a long way in keeping the code base maintainable. Explicit declaration of dependencies was a goal which would also help to improve build time.
What’s in Go ?
The design goals mentioned above laid the foundation for Go’s features. What did they achieve after they had set out to build the language?
In summary, they were able to build a language which is easy for humans and efficient for machines. Let’s explore a bit more.
The human angle
The language has a simple, concise syntax, which has only 25 keywords. Less keywords meant less complexity with the runtime. Basic syntax is mostly C-family, with some inspiration from Pascal, Modula and Oberon for declarations and packages. The statically linked binaries approach reduces run time complexities even further.
Built-in concurrency constructs allow programmers to write multi-threaded applications in an easier way. Go uses a different approach called goroutines, which are light-weighted threads, for multi-threading. Communication and synchronization between goroutines are handled via a typed thread-safe mechanism called channels; Built-in support for generic maps, arrays and slices too improves coding experience.
The machine angle
Go programs are compiled into machine code. This improves performance significantly since there is no middle layer, such as a VM, involved. Being a garbage collected language allows programmers to not worry about memory management. Memory safe mechanisms such as nil references, runtime bounds checks and default initialization of variables help at run time. Interfaces are used to implement composition.
What’s not in Go?
Does that mean Go has everything? Certainly not. The designers made some choices on what not to include.
Go does not have sub-classes nor does it support inheritance. It takes an unusual approach to object-oriented programming by allowing methods on any type, not just classes. This is done without any form of type-based inheritance like sub-classing.
There are no constructors or destructors. No control structures associated with error handling, similar to the try-catch-finally paradigm, is available. It does not have pointer arithmetic, annotations or implicit numeric conversions. And, a few more missing features.
Hmm.. that doesn’t sound very assuring, isn’t it. Let’s try to understand the rationale behind it.
Why are some features left out?
In normal scenarios, most languages would like to add as much features as possible. But, in case of Go, as you can see above, many features were left out. That was an intentional choice. There are many reasons to do so.
One of the main aspect is, clarity was considered as a critical feature. When reading code, it should be clear what the program will do. When writing code, it should be clear how to make the program do what you want. Sometimes this means writing a bit more clearly instead of invoking an obscure function.
Do more with less
More features does not necessarily translate to better language. In Go’s case, “less is more”
(Though generics are not available as of now, there is a proposal, which has been accepted by the Go team, to introduce generics at a later release. For more details, refer here.)
Go vs Other languages
When you want to choose a programming language for your next product/project, it is imperative to do a comparison with other languages. Let’s give it a shot in doing so.
Please note that, this is a very high level comparison. A detailed comparison would warrant an article on it’s own. So, here, we’ll try to discuss a few main aspects.
Compared to C/C++, Go has explicit dependencies. Circular dependency is not permitted. There is no need of header files. The files are compiled together in to a single binary. A garbage collector manages the memory clean-up activities. Memory is always initialized with default values (zeroed). Though pointers are present, there is no pointer arithmetic. Go does not have constructors or destructors. Strings, slices and maps are built-in as part of the language.
One of the common complaint against Java is its verbosity. Compared to Java, Go is less verbose. There is no mechanism similar to JVM. Since Go was designed from ground up with concurrency in mind, the concurrency support is much better. Instead of threads, Go uses another mechanism called goroutines, which can be considered as a light-weighted thread. Communication between goroutines are handled via channels. Unlike Java, Go has pointers. Functions are considered as types, which permits functions to be used similar to any other types; Java permits single result to be returned from methods; but, Go allows multiple values to be returned from a function. (Note that, Go has both functions and methods. The equivalent of Java’s method in Go is function. A method in Go is different from a function.)
Go is a statically typed language, where Python is dynamically typed. Due this nature, Go offers type safety. It is compile language, unlike Python, which is interpreted. It is much faster due to the same reason. Unlike Python, Go has in-built support for concurrency.
What can we build using Go?
There are many usecases where we can use Go.
Another area were Go shines well is DevOps & Site Reliability Engineering. Building such tools in Go provides a better performance.
You can also use Go for web development as well. It has good support for protocols such as HTTP/2, databases such as MySQL and PostgreSQL.(Though you can develop web UI in Go, personally, I wouldn’t recommend doing that.)
Where does Go stand now?
How does Go fare in the industry now? More than 75% of the projects in CNCF (Cloud Native Computing Foundation) are written in Go. TIOBE declared Go as the Programming Language of the Year twice: in 2009 and 2016. Though Go was initially designed as a “system” language, it has now matured as a “general-purpose” language.
Who uses Go
When choosing a language for your product, one aspect to consider is the industry wide adoption. In case of Go, it has come a long way since it’s inception and attained good level of industry adoption. A full list of Go users can be found here .
Thank you for reading so far. Till we meet next time, happy coding!
I highly recommend you to go through the reference materials used for this article. It provides much more insights into Go’s origin story, design goals and feature set. Some of them are mentioned below.
Disclaimer: Please note that, views or opinions expressed here are my own and do not represent any organization.