Get concurrent with the Go language

Google's Go language is perfect for today's distributed application development, enabling complex operations across multiple services to run concurrently

What happens when the people behind one of the most influential operating systems of the last 50 years or so decide they don’t like what’s happened to the language they wrote their OS in? 

It turns out they decide to rebuild it their own way. That’s what happened when Unix creators Rob Pike and Ken Thompson (who wrote the original B language that formed the foundation of the entire family of C-derived languages we use) felt it was time to develop a new systems-level programming language, with a focus on speeding up software development.

Working with Robert Griesmer at Google, they created Go, a C-derived language with static typing (using type inference where necessary to ensure type-safe code), along with such features as garbage collection that are usually associated with dynamic interpreted languages such as JavaScript or byte-code languages such as Java or C#.

In the five or so years since Go was announced, it’s become the basis of many production systems at Google, because it contains constructs required for concurrent programming -- making it a useful tool for cloud-scale distributed application development.

Go from the ground up

Like C, Go programs are made up of packages, with program execution handled by the main package. Imported packages and libraries can be called from here. A simple naming convention handles exported names -- names in a package are only exported if they start with a capital letter.

Typing is handled by a mix of static and dynamic techniques, so your code is type-safe, but it’s easy to write and understand. For example, if two or more consecutive parameters in a function have the same type, you need to declare the type only once.

One interesting feature is the ability to define your own types, allowing you to create specific types for recurring variables -- for example, declaring a type that’s an ITU-standard telephone number. Declaring a number that’s not the right format as a telephone number would return an error, allowing you to write code that handles data checks at a very low level.

If you’ve programmed in C or C++, it’s not difficult to get started with Go. There are a lot of similarities, and where differences emerge, it’s not hard to pick up alternate ways of working -- for example, the way in which Go uses interfaces instead of inheritances.

Perhaps the biggest difference between Go and other modern languages is how it handles errors. There’s no try-catch construct, because the designers felt that would make the code too complex. However, Go’s multivalue returns mean there's an error return type that functions and methods can use, which makes it possible to write your own error-handling code.

Working together

Where things get really interesting for cloud-scale development is in Go’s explicit design for concurrent programming.

Based around the concept of Communicating Sequential Processes, Go uses a model similar to that of such functional languages as Erlang or Occam (the language developed for INMOS’s innovative multiprocessing Transputer processor). The result is a series of separate blocking functions implemented as lightweight processes, known as goroutines.

Goroutines can be moved to nonblocked threads to allow a program to continue to run. Keeping goroutines separate from threads allows a Go program to use much less memory, minimizing the use of system resources. It’s also an automatic process, so there’s no need for developers to write code to handle blocking events.

Goroutines can be connected by channels, simple structures that let you send values between concurrent processes. This is where Go’s process communication comes into play; it gives you the tools you need to pass messages between processes to trigger appropriate actions. Channels are synchronized, type safe, and work with send and receive statements. Data is sent and received over defined channels, with channels blocked until the communication operation has completed.

What Go is good for

The result is a set of language tools that can be used to build distributed applications, using channels to link goroutines and to handle how data is passed between them.

There’s the option of making channels buffered, for sending larger amounts of data -- letting you work with streaming data from IoT devices, for example. A buffered channel will send data until it fills, at which point it blocks until emptied by the receiving process. Similarly, a receiver will block until it receives data, giving you a mechanism for basic flow control for streamed data. Once data has been transferred a sender can close a channel, though in practice, you’ll keep a channel open for additional data transfers.

Tools like this make Go a useful tool for building servers -- and microservices. You can use Go’s select statement to manage communication across channels, with goroutines that open new channels as they unblock and picking channels at random if several are needed at the same time. It’s an interesting approach to building parallel code and compares well with other language’s approaches. You’re also able to build timeouts into channels, so they don’t halt execution waiting to send data.

One of Go’s creators, Rob Pike, compares the concurrency model in Go to the world outside the computer -- where independent pieces interact. Using concurrent techniques like these means that code can scale from one CPU to many to a cloud-scale cluster of machines. It’s a philosophy Pike encapsulates as “don’t communicate by sharing memory, share memory by communicating.”

You can see why Google uses Go. It allows complex operations across multiple services to run concurrently, so a search can be working with Web, image, and video goroutines, bringing in results from them all and delivering them in one function return. The resulting code is not only faster (because it’s not sequential), it’s also more robust: If one search channel doesn’t respond, you can open another.

Go is now one of the standard languages for Google’s App Engine PaaS, with compilers for most common OSes, including Android. There’s also a live playground for trying out Go code on the Go website (it’s also built into the language tutorial so that you can try out code snippets as you go). If you want to work with Go, then you’ll find plenty of development tooling support, with cross-platform IDEs widely available, as well as support in modern code editors like Sublime Text.

Copyright © 2015 IDG Communications, Inc.