It's been 10 years since a Google team around Robert Griesemer, Rob Pike and Ken Thompson introduced the programming language Go. They had invested two years to develop a fast, easy and up-to-date language for networked systems. The success was unclear.
But already in early 2010, the TIOBE programming language index Go named the language of the year 2009, so great was the interest. There were still many restrictions. The language already looked similar to today, but used even more Semikola. And the practical
goCommand did not exist yet, depending on the architecture compiler and linker in the form
6l, They were manual or in makefiles. A casual one
go build like today did not work yet. In addition only Linux and macOS as operating systems as well as x86 architectures with 32 and 64 bits as well as ARM with 32 bits were served. After all, already worked the Cross Compiling, for example, to develop on the Mac and to create a binary for the Linux server.
In terms of speed, Go reaches a high level right from the start, especially when compiling. 10 seconds for 584 files with a binary result was a whole new sensation. This creates programs without dependencies on external libraries, a handy feature for server deployment. And the execution speed was almost as good as that of C from the beginning, but was slowed down in the first days again and again by the garbage collection.
But what was special about the language?
Actually nothing – which has led to so many with a strict rejection. The developers focused on simplicity and pragmatism. At its core, Go was imperative; its object orientation knew methods and interfaces, but did not use inheritance. The language had function types, anonymous functions, and closures, but it was unable to match full-fledged functional languages. In addition, there was the abandonment of threads, for the Go, however, introduced a "lightweight" concurrency with goroutines and channels.
For proximity to dynamic languages, in addition to the above-mentioned garbage collection, a simultaneous declaration and assignment of variables via
: =, Hereby were terms like
n, err: = myFile.Write (myBytes) possible.
n as number of written bytes and
err as potential errors were not previously via
var to declare, even if that was also allowed.
Interfaces generally were not unknown at the time, but often so that implementing types had to announce this. This creates dependencies on the defining package. Instead, Go followed the duck typing from the beginning. An interface is defined by the user and reduces to as few methods as possible. Implementing types do not need to specify their interfaces. This type of use of interfaces does not miss the missing inheritance until today. An example is the interface
fmt.Stringer for all types with the method
String () string, The functions of the package use this method for the representation of the respective instance as a character string.
In addition, from the outset, there were also overarching concepts that went through the entire system. So had the package
io among other things via the interfaces
Writer, They only define one method each for writing or reading bytes. But they are used in many packages and pull themselves through the system. So for the files or buffers, for the networking and the cryptography, for the encoding and the compression, they play together. A nice example of the interplay of function types and interfaces is the package
http, It has the interface
handler, that the
server uses. It only defines the method
Serve (HTTP), The server is therefore satisfied with everything that implements this method, such as the function type
Serve (HTTP) just calls the function itself, so this is automatically a handler.
Concurrency far ahead
The above-mentioned concurrency was present so far only in a few languages. Erlang / OTP has already known them, albeit in the form of sending messages to lightweight processes, which are distributed to threads by the runtime environment. On the other hand, Go introduced goroutines and communication via channels, based on the work of Tony Hoare on Communicating Sequential Processes. Similar to Erlang / OTP, it pursued the idea that lightweight processes consistently manage states through sequential processing. They were changed in Go through signals and data sent via channels, and information was also returned to the sender. Thus, this language was also given the opportunity to work thousands of concurrent processes without having to worry about semaphores or mutexes.
Today and tomorrow
Today, 10 years later, not much has changed in the scope of the language. It has version 1.13, and the developer's promise is syntax compatibility with the same major version number. The standard library has been extended and improved, the runtime environment has become faster and now serves twelve operating systems and ten computer architectures. And also the memory management is in the meantime on the current state of the art.
In addition, the tooling has also evolved. The linchpin is the command
go with its subcommands for source formatting, module handling, builds, temporary runs, installations, tests, benchmarks, and more. However, the said modules are just starting to spread in the world of go projects. They contain some rules when dealing with major versions that are still being discussed in the community.
While currently working on the Go 1.14, about every six months appears a new subversion, is also already discussed around the future major version 2. In addition to smaller issues, there are specifically two topics that are important to the community. The first is the introduction of generics for more flexible data structures, the second is to facilitate error handling in functions and methods. Both are nice extensions, but their code can no longer be used in 1.x projects.
The goal of the authors of the language were scaling, networked systems – today also called succinctly as cloud-native. And here Go feels comfortable, it's found in many systems for building and managing cloud environments. Here Docker and Kubernetes are the best known representatives, but also Etcd, Prometheus, Terraform, Istio, CoreDNS, containerd and Juju.
Anyone who works in this system world can understand the success of Go herein. The pragmatic approach, the straightforward language, the fast turnaround times from the source to the compiling to the tests, the very good support of networks and cryptography and finally the elastic scalability up to a high number of cores on a system are fun.
As already mentioned, commercial systems could profit from this. So if we wish you all the best for your birthday and a successful future beyond the world of cloud native applications. Happy Birthday, little gopher (= the mascot of the programming language).
See iX and heise Developer:
(Frank Muller) /