Channels ▼

Open Source

Why Not Go?

Earlier this year, we ran an article about the emerging crop of native languages. The group included D, Go, Rust, and Vala. I promised then that we would eventually explore these languages in greater detail. This week starts that fun journey with what will be a five-part series on Go, the new language from Google. Unlike past tutorial series in Dr. Dobb's, we will run the articles in consecutive weeks, so that you can be up and running quickly.

More than the other languages on the list, Go really attracts me. While I am by no means an expert in it, I like what I've seen so far. My enjoyment derives, as you'll see, from an appreciation of the maturity of feature selection, rather than from a gee-whiz enthusiasm that new languages can generate on first exposure. (I confess I am susceptible to this kind of excitement as well—which is why I can recognize the difference with Go.) These features in particular appeal to me:

Fast and simple compilation. Go compiles fast. In fact, it compiles so fast, it can easily be used as a scripting language. Several reasons for the compilation speed are that it does not use header files; if a module depends on A, which in turn depends on B, a change in A requires only recompiling the original module and the A dependency; finally, the object modules contain enough dependency information that the compiler needs no make file. You simply compile the main module and it will automatically compile everything in the project that needs to be updated. Cool, eh?

Error handling through multiple return values. There are two primary paradigms today in native languages for handling errors: return codes, as in C, or exceptions, as in OO alternatives. Neither system is ideal. But of the two, return codes is the more frustrating, because returning error codes often conflicts with returning other data from the function. Go solves this by allowing functions to return multiple values. One value that returned for functions that you designate is of type error and can be checked anytime a function returns. If you don't care about the error value, you don't check it. In either case, the regular return values of the function are available to you.

Simplified composition (in preference to inheritance). Types can be qualified as members of a group of objects by the use of interfaces, which, like they do in Java, specify behavior. So, for example, the io package in the standard library defines a Writer that specifies one method, a Write function with array of chars as the the input parameter and return values of integer and error type). Any type that implements a Write method with the same signature is a de facto implementation of the io.Writer interface. This design decouples code rather elegantly. It also simplifies mocking objects for unit testing. For example, if you want to test one method in a Database object, in standard languages you have to create a database object that requires lots of initialization and protocol in order to create the mock. In Go, if the method under test implements an interface, you can create any object with that interface and you're good to go. So, you could create MockDatabase, which is a minimal object that implements only the few methods necessary to run the interface that needs to be mocked—no constructor, no added features, just the methods.

Simplified concurrency. Concurrency in Go is made comparatively easy. Put the keyword 'go' in front of any function and that function will run in its own go-routine (a very light thread). Go-routines communicate through channels that are essentially blocking message queues. The usual tools for mutual exclusion are available, but Go makes it simple just to kick off concurrent tasks and coordinate via channels.

Excellent error messages. No language I've seen comes close to Go in the quality of the diagnostics it emits. For example, if a program deadlocks, the Go runtime notifies you of this and, to the extent it can, tells you which threads are causing the deadlock! Compiler error messages are similarly detailed and useful.

Grab bag: There are other appealing features, which I'll quickly run through here: higher-order functions, garbage collection, hash maps and expandable arrays built into the language (so part of the language syntax, not brought in as a library), and so on.

Of course, not everything is rainbows and lollipops. The tools are still fairly immature and the community is small, but with Google behind the language, both aspects are sure to be remediated. While many languages—notably D, Rust, and Vala—aim to simplify C++ and add specific features, they all feel to me like “C++ with better features.” In Go, however, there's been a fundamental rethinking of how native languages should operate. And from that perspective comes an elegance of implementation that does away with many problems. Even if you have no particular need to consider Go, I think that by kicking the tires on the language, you'll find yourself appreciating many of its features. Cheers!

Related Reading

Go Tutorial: Object Orientation and Go's Special Data Types

Getting Going with Go

RESTful Web Service in Go Powered by the Google App Engine

A Brief Tour of the Go Standard Library

Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.



You are forgetting to take Lua into account:
It's a awesome language that can also be used as a "glue" language. Today it's the world leading scripting language in games!


Looking at the Go documentation its just syntax sugar for returning a container type object. You could argue its a few less characters than typing pair< int, int >, but nothing I would lose sleep over.


@Devx "...this always makes me smile. In C I return a two field struct..." If you actually do this regularly, then I would expect you fully understand why having multiple return values returned within the language proper is a far superior solution.


"Error handling through multiple return values." this always makes me smile. In C I return a two field struct and in C++ I use std::pair< return_value, error_code >.


There is a reason why programmers are known for reinventing the wheel. They all think their way is at least a little better. Standard usage eases understanding of the code, so should trump change for changes sake. BS did not like the cast syntax in C, so he added function style casting to C++. I am sure that even he knows now that this was a blunder. Most of the Go features could have been done as a strict superset of C, preserving the familiar in preference to fixing minor issues. Changing the declaration order was necessary for multiple return values, but caused the need for the func keyword, and is very confusing to longtime C programmers.


Sure, as already discussed in Lambda the Ultimate,

- exceptions;
- enumerations;
- generic types;
- direct use of OS APIs, without the need of writing wrappers (cgo);
- currently only static compilation is available;
- no support for meta-programming;
- rich set of available libraries;
- the PR about go routines and channels, usually forgets to mention that similar features do exist as libraries for other languages

Go seems to be a Limbo for the rest of us, given Plan 9's fate. While forgetting a lot of what has happened in language research field and industry in the last two decades.


Would love to hear what the missing abstractions are.


While I find Go a nice evolution over C in what concerns strong typing and module based compilation, I think the language sins by being too minimalist.

It just leaves out too many abstractions that are nowadays expected in mainstream languages.

Personally I've decided to invest my time in D and Rust, after a year of playing around with Go.


C is not a minimalistic language. Pointers and side-effecty operators like ++ itself are not minimalistic. On the other hand it is minimalistic in bad ways, like equating 0, null, and false, confusing '=' with assignment, needing 'break' after every case in switch. We can only hope that Go gets minimalism right because C certainly does not.