GO with the Flow image

The frequency with which new programming languages see the light of day is continuously increasing. One of these, Go, is a relatively new programming language that is becoming increasingly important. Go programming language, which was only introduced to the public in November 2009 and declared ready for production in May 2010, has been growing strongly in popularity for some time now, because with every technical development and every new programming concept, deficits are revealed in the established, old programming languages. No other language has been able to grow so rapidly in recent times.

But, what exactly was the main driving force behind the development of Go? Simply, there had been no new major system language for a decade. Technical peculiarities in the underlying environments of software solutions changed dramatically. When Rob Pike presented Go in the Google Talks in November 2009, he spoke of:

- Applications that have extensive libraries and dependency chains
- Dominance of networking
- Client/Server Focus
- Massive Clusters
- Multi-Core CPU's

In application development, all these points are now gaining more importance. However, system languages were not designed with all these factors in mind. So, what exactly differentiates Go from other system languages? Let’s discuss this in this article.

Two Worlds United

Go (often referred to as GoLang) is still considered a new programming language, even 10 years after its release. The development of Go was driven by Google to increase programming productivity while addressing the environmental characteristics mentioned above. Go programming language itself is imperative and modular, borrowing from object orientation and functional languages. Experience with numerous languages, including C, C++, Java, Perl and Python, was incorporated into the development. However, Go is syntactically similar to C, but with memory safety, garbage collection, structural typing and Communication Sequential Processes (CSP) concurrency [1].

What is impressive is that Go has been consistently designed for practical use and almost completely does without the introduction of entirely new features and paradigms. It is an imperative programming language, i.e. the instructions of a program are processed in the order of the source code. Parallel processing is possible both explicitly (using goroutines) and implicitly (by reordering in the compiler and or the CPU). However, when accessing global variables, there are precisely defined rules for sequence and synchronicity.

Go is also modular. Each program consists of one or more modules (packages). Modules specify namespaces that cannot be broken, and visibility rules for self-defined variables, functions, and other identifiers.
Go has some characteristics of functional programming languages such as First-Class functions (functions that can be used as parameters or return values of other functions) / High-Order functions (functions that have functions other than parameters or return values), functions with multiple return values, variable functions, anonymous functions and closures. However, Go is not a real functional language. For example, functions can have side effects, and there is no strict call-by-value semantics.

Developers do not refer to Go as an object-oriented programming language, although many of the properties of object-oriented languages are present. There are no classes; instead, methods can be defined for all self-defined variable types. There is no inheritance hierarchy, but in many situations similar structures can be achieved by composition, i.e. a data type contains another type and uses its methods. There is no access control to the data of an object; instead, the visibility rules for modules can be used as access protection.

Interfaces are a central concept of Go. These define a list of methods that a data type must have to correspond to the interface. If this is the case, values of a specific type can be assigned to interface variables. This makes polymorphism possible: any objects can be passed to a function whose parameter is an interface variable, provided the type fulfils the interface. The function can call the methods defined in the interface directly.

Go supports concurrent or parallel programming through goroutines. These are based on the Communicating Sequential Processes defined by Tony Hoare in the 70s. A goroutine is a very lightweight, concurrent execution unit. Initially, it needs only about 2 kB memory, so that one million and more goroutines can quickly be started on current systems. Other parallel languages, on the other hand, often map concurrency to operating system threads, so that several thousand of them are already problematic. For concurrent programming, there is the data type Channel, which implements a type-safe communication channel. It is used for the exchange of messages and between goroutines. There are buffered and unbuffered channels; the former has an adjustable capacity for buffering messages and thus support pipeline-like data processing. Unbuffered channels enable bilateral synchronisation between goroutines.

Simplicity Is The Key

There are only 25 keywords in Go (cf Java’s 57 reserved keywords [2] and Python’s 33 reserved keywords [3]) and 39 additional predefined identifiers. These keywords define the basic syntax of Go programs and must not be used as names for self-defined variables, functions or the like. In Go version 1 (go1.12.4 was recently released), a guarantee was made that no further keywords would be added to the language. If this happens, the corresponding words will no longer be available for custom definitions, and existing programs might no longer be compiled.

In comparison to language monsters like Java, Go has a minimal amount of language resources. Within the 25 keywords, there is only one loop (for-loop), there are no classes and no inheritance, there is only one form of interface, there is no generic programming, there is no pointer arithmetic, there are only two levels of visibility (public and private), there are no constructors and destructors, and minimal reflection. Even though these limitations exist, they do make the language very easy to learn.

In addition, Go is a statically typed programming language. Errors in the use of types are flagged during compilation and cannot cause a program to crash at runtime which makes it faster to identify flaws in the source code. Conversions between types are possible within certain limits, but in contrast to other languages, they must be explicitly written out to avoid ambiguities and accidental conversions.

As mentioned previously, there is only one type of interface that can be used to implement Polymorphism. An interface variable can be assigned values of different types, provided they match the interface, i.e. have a specified set of methods. Type assertions can be used to recover the original data types, whereby runtime errors are possible if not all possible states have been considered during programming.

In Go, it is not possible to explicitly delete an object. The runtime environment automatically recognises when an object can no longer be used (for example, because the scope of its visibility has been left and there are no references to it), and deletes it using automatic memory clean up. Since the deletion takes place later, a Go program often uses more memory than a comparable C or C++ program. However, the garbage collection prevents an object that has already been deleted from being referenced again. This avoids other objects being accidentally overwritten without control, potentially preventing a program crash.

Future Development Perspectives

The simplicity of its neat syntax and the very high performance and low memory footprint are the most significant advantages of Go [4]. Go runs directly on the underlying hardware and is not executed on a virtual machine, like Java, which means that program code is compiled directly to a binary file, making it faster.

The low memory requirements of the Go programs and the integrated parallelisation make the programming language particularly suitable for specific application areas, such as use in the cloud.

Go programming language is easy to learn, especially if you already know another programming language.

Go code contains practically no surprises. Its limited language resources lead to an absolute uniformity of the source code (independent of the author) which facilitates later maintenance. One could also say that tedious code is good in the long run. Go is platform-independent and can be used on different operating systems by just setting an environment variable before compiling the package. There is no additional runtime necessary for the target environment that needs to be managed.

Ref:
[1] https://en.wikipedia.org/wiki/Go_(programming_language)
[2] https://en.wikipedia.org/wiki/List_of_Java_keywords
[3] https://www.programiz.com/python-programming/keywords-identifier
[4] https://benchmarksgame-team.pages.debian.net/benchmarksgame/faster/go.html