Beauty is in the eye of the coder
Go is rooted in a 1978 researcher paper from Tony Hoare, the British computer scientist who would win a Turing Award for his work on programming-language theory. While at Bell Labs in the late 1980s, Rob Pike drew on Hoare's paper – "Communicating Sequential Processes" – when creating a language known as Newsqueak, and when he sat down with Thompson and Griesemer to build Go, many of the same ideas resurfaced.
Like Newsqueak and Hoare's theoretical CSP before it, Go was fundamentally designed for concurrency. That's concurrency, not parallelism. Concurrent programs may or may not be parallel. "Parallelism is the ability to make things run quickly by using multiple processors," says Rob Pike, the man known as "Commander Pike" on the Go mailing list. "Concurrency is a completely different concept. It's the idea that sometimes a program can be decomposed into structural things that are easily solved independently, and the program itself gets prettier as a result."
But with Go, beauty wasn't a primary aim. Pike and crew had a far more concrete goal. They needed a better way of building the systems that drive Google's back end. "Web servers, but also storage systems and databases. That kind of thing," Pike says. "The world is concurrent and parallel. But the programming languages we use to interact with the outside world – through users on the web and mice and keyboards on a local machine – they don't tend to support that way of thinking about things very well. There was a lot of interesting theory work on this, but very few practical languages."
The idea was that Go would provide concurrency in way that was actually useful. It wouldn't be a programming language you merely gazed at. It would be a programming language you programmed with. Pike calls this a "compromise", betraying a bit of a soft spot for pure programming theory. "Go is a little bit of compromise because it offers very nice support for concurrency, but it's also intended to be very efficient," he says. "You can write realistic server software that can handle a very large load."
This means that Go would be a compiled language, like C. But at the same time, it would be far easier to use than C. Pike wanted something that struck the right balance between the low-level and the high. It would be a compiled language, but it would feel like an interpreted language. It would be statically typed, but it would provide the flexibility and simplicity you expect from a language that's dynamically typed.
The end result is a concurrent language that Google bills as a cross between C++ and Python. "For large programming - programming in the large, like we do at Google, using large systems with many programmers working on them - static [typing] is a huge safety net. It catches tons of stuff early that would not be caught with all-dynamic typing," Pike says. "Go is a real systems language, a compiled language. You can write really efficient code that runs closer to the metal. But you can use these higher-level ideas to build servers out of the pieces you put together."
If it walks like a Python and talks like a Python...
Yes, for the most part, variable types are strictly checked at compile time. But Go automatically manages memory with garbage collection, and using a new concept called an "interface" – similar to but a bit different from a Java interface – there are cases where you can pass data structures and variables without defining a strict type. Go interfaces provide something similar to "duck-typing" in Python and Ruby, letting you pass any variable as long as it exhibits a certain behavior. "There are properties of programs that work better when you have different implementations at runtime," Pike says.
For instance, he explains, one interface is provided by a library called a "writer". To use a writer, you don't need to know what's doing the writing. All you need to know is that it's a writer. "Lots of things can be writers – networks, files, pipes, buffers, http connections," he says. "That means that anything that knows how to use a writer can use those resources to present data." This is reminiscent, he adds, of a "behavior" in object-oriented programming.
For many, the language lives up to its billing. "I've been dreaming about this sort of type safety in a language for awhile, and they've pulled it off," says programming consultant Chip Camden. "There is type safety when you want it, but you can also use an interface, so anything that implements the interface can be passed. This is sort of similar to the Java concept, but Java – as usual – makes it a hard thing. Go makes it an easy thing.
"With Go, all you have to do is provide [something] that implements the interface. You don't have to say it implements the interface. It is, in a sense, like duck typing, but it's still verifiable by the compiler, so it catches problems for you before they start crashing your website."
Go is object-oriented, but it's not type-oriented. There's no hierarchy, and there's no sub-typing. The compiler can determine the relationship between types. "If you're in a programming language like Java and you want to declare some sort of object, there's all this ceremony around just saying what the variable is," says Charles Thompson, a longtime developer who's writing a book on the language. "Go doesn't make you do all that. It just says 'Oh, you're setting a variable equal to this object. I know that its that type of object.' The code is just so much simpler."
What's more, says Brian Ketelsen, who runs a consulting businesses dedicated to Go and Ruby and is also working on a Go book, the compiler is much faster than the norm, and this too adds to the dynamic feel. "The compiler is lightning-quick," he says, "so the turnaround time on a compile is less than it takes to spin up the virtual machine on an interpreted language like Ruby or Python."