Graham King

Solvitas perambulum

Go @ Vancouver Polyglot Unconference

Summary
I attended Vancouver’s Polyglot Unconference, met great people, and presented on Go (#golang). I proposed a model for prioritizing what to learn, highlighting the intersection of intrinsic interest, longevity, and practical use. Go fits this space well as a general-purpose programming language with robust concurrency support, backed by Google, its open-source nature, and a strong development team. It combines the power of C with the simplicity of Python, offering an extensive standard library and easy dependency management. Although it lacks an interactive interpreter and suffers from a vague name, I found Go enjoyable and effective for server-side development, making it a worthwhile cognitive investment.

I attended Vancouver’s Polyglot Unconference, met some wonderful people, and got to present a session on Go (#golang). Here’s broadly what I said:

How do you decide what to learn?

You have an amount of cognitive resources to spend every day, what do you invest them in? You have a pile of books at home you’re going to get to, a growing list of “read later” bookmarks, and a list of tech you’ve been meaning to play with. Hopefully that list will be even longer by the end of today.

I’d like to propose a model for prioritising what you learn. And I’d like to share why I think Go is worth learning.

Picture a Venn diagram, three circles, with their intersection about where I’m standing:

  • The circle on my right is really interesting things, things that make you go “wow!” or “huh?!”. We shouldn’t learn things because we think they pay well, or because someone else wants us too. We need intrinsic motivation.
  • On my left are things that will stick around, things that will be here in five or ten years. Given two equally interesting things, I prefer to learn the one that I will use the longest. Unix, for example, is a good investment.
  • Above me are things of practical use. I prefer to invest time in things that I will use regularly.

Here in the middle, at the intersection of the three, are things worth learning, and I’d like to share why, for me at least, Go fits in this middle space.

Go is a general purpose programming language, initiated at and supported by Google, open source (BSD), which feels somewhere between C and Python, has fantastic concurrency support, and gets all the small things right.

Will make it

I’d like to spend most of the time talking about why it’s a really interesting language, this circle, but first I’d like to place it here – things that will be here in 5 to 10 years, for four reasons:

  1. It’s really open source, under a BSD-style license, with an added patent grant. We won’t have the Java / Oracle thing. When you submit a patch, you have to submit a contributor license agreement, similar to what the Apache Software Foundation uses.
  2. It has Google’s resources behind it: A paid dev team, and an active evangelism effort.
  3. Google is using it internally. So is Atlassian, Canonical, Heroku, and many others.
  4. Created and developed by some pretty experienced individuals, which generates interest and builds trust:
    • Ken Thompson, of B, C (yes the programming language), Unix, and Plan 9 fame.
    • Rob Pike of Plan9, co-author of The Unix Programming Environment and The Practice Of Programming. Designed UTF-8 with Brian Kernighan on a place mat in a diner in New Jersey one evening.
    • Robert Griesemer: Worked on the V8 javascript engine and Java’s HotSpot Compiler
    • Brad Fitzpartick: Memcached, Gearman, Perlbal.

Is good:

Here’s Hello World in Go. As you can see it’s definitely C-family. Everything has to be in a package, and an executable needs a main package. Execution starts at the main function.

The golang.org website allows you to play with the language online. It’s like an executable pastebin. That means sharing code and helping others gets a lot easier – we’re all talking about the same code, and we can check fixes immediately.

Go has everything you’d expect from a modern language: All Unicode. Built-in string, map and array types. Garbage collection. Unit testing. First class functions. Closures. Reflection. Multi-core support. etc

You can easily link / wrap C libraries.

Let’s look at something a bit more interesting:

package main

import "fmt"

// Interfaces
type Priceable interface {
    getPrice() float64
}
type Aquatic interface {
    Priceable
    GetName() string
    IsCompatibleWith(Aquatic) bool
}

// Object
type Fish struct {
    name    string
    compat  []string
}

func (self *Fish) GetName() string {
    return self.name
}

func (self *Fish) IsCompatibleWith(candidate Aquatic) bool {
    for _, name := range self.compat {
        if name == candidate.GetName() {
            return true
        }
    }
    return false
}

func main() {
    goldfish := Fish{
        name: "Goldfish",
        compat: []string{"Goldfish", "Tetra"}}
    fmt.Println(goldfish.GetName())
}

Compiled, very fast compiler. Statically typed.

Interfaces, no classes, duck typing. Composition over inheritance. There are no constructors, the convention is to make a function called NewMyType. Object’s feel a lot like C.

Small language with readable spec, extensive “batteries included” standard library. Lots of third-party libraries Drivers for most things: MySQL, Postgres, Redis, Memcached, MongoDB, etc.

The most exciting part of Go is it’s concurrency support. It was designed as a language to write servers, although it’s now billed as general purpose.

Starting a Go routine, and select

Putting data on a channel

Great concurrency support. go starts a go-routine, which you use instead of a thread or sub-process. Each go-routine has tiny memory footprint, and is very cheap to create and tear down (much cheaper than a thread or process). The runtime might move your go-routine to a different core for you.

Channels are how you pass data between go-routines. select listens to multiple channels. On linux it uses epoll internally.

This means there’s no C10K problem. No callbacks, which I find hard to follow. Everything is blocking. Multi-core support is free.

This is the same concurrency model as nginx. Here’s an efficient static file server in Go – you might not need nginx:

package main

import "net/http"

func main() {
    http.ListenAndServe(
        ":8080",
        http.FileServer(http.Dir("/usr/share/doc")))
}

Here’s a very simple webapp I wrote: plebis.net. Here’s the entire source code for plebis

Note the request object, and the templating. Go has a basic web framework in the standard library.

In Go you don’t create webapps, you create custom web servers.

The unit of deployment for your webapp is a compiled file (plus static assets). scp to win!

Most languages, you need to learn a whole ecosystem: the language, the standard library, the package manager, deployment and hosting tools, the web framework, the list goes on. In Go these are either unnecessary or built-in.

Dependencies: You can declare a dependency (import) on a github project (any git, hg, bzr, svn). When you go install myproject it will download the dependencies, build them, and install your project. This is like pip / gem / maven / etc, but with the Internet as the repository!

Downsides

  1. I miss Python’s interactive interpreter. play.golang.org partly compensates.
  2. Go is a poor name, because it is difficult to search for. The convention is to use “golang” instead. Ken Thompson’s previous languages were B, and C, so we’re probably lucky it’s not just called G.

Summary

I think Go will make it. I hope to of convinced you that it is interesting, and useful. Hence I believe Go is worth your cognitive investment.

I personally found it a joy to use, and easy to learn. The power of C with the ease of Python. No earth shattering paradigms, it just gets all the small things right. Go does for writing servers what Perl and Python did for text processing.

What are your questions? I know other people have been playing with Go, maybe you can share your impressions?