Wading into Go

From Python to Go

We dove into Python years ago and now are wading into the Go language.
Our team’s been using Python for a hells age, building applications in Plone, Django, Flask and Pyramid. It’s been very good to us and the communities are full of bright folks who are willing to share what they know.
We’re now embarking on a couple projects where we want to decouple front-end from back-end, rendering from API, and we’ve got some 3rd party back-ends we need to talk to very quickly. For these apps, we’ve settled on an architecture with a responsive front-end powered by AngularJS talking to an API server written in Go. Why the switch to Go?
One of our projects involves making lots of calls to a third-party back-end information service: to render the results of  a user query, the code typically has to make over 30 queries to a different endpoints, and these request/response cycles typically took about 1/8th second each.  Our initial Python-based API was single-threaded so it took almost 4 seconds to render the results page; not gonna make our users happy.
We’ve poked at using gevent to get concurrency and that works in our development environment, but we’re deploying these apps in the cloud — Amazon Web Services (AWS) for one client and Google App Engine (GAE) for another.  We’re not comfortable that GAE can run the compiled code that gevent is built upon so we looked to Go to give us the concurrency we need.

What I’m Liking

Concurrency

There are a number of other reasons why we’re interested in Go, but for this particular application, the concurrency features built into Go are compelling.
Since concurrency (via “goroutines”) is built-in, it’s natural, feels right. Communication and synchronization via “channels” feels good too, light-weight, again, natural.  I’m still wrapping my head around how to use these idiomatically — the Effective Go doc has some examples that twist the way I normally think about coding. And that’s just fine, I need new ways to approach problems. I’m really looking forward to adopting these patterns.

Compilation

Before discovering Python at the last PyCon hosted in DC, I’d been coding in Java and doing multi-threaded C. While I like Python’s interpreted nature, Go’s compilation doesn’t bother me — it’s plenty fast.

Compilation isn’t necessarily a “plus” in my book, but we expect to see speed-ups in our most intensive code. Perhaps more importantly, Go’s fast compilation allows other tools to work quickly, and that allows us to integrate them into our working process; see below on Editors.

I also expect that a blob of compiled — complete with all its (versioned) dependency modules — will make deploying to platforms easier and more reliable: no worries about OS library version mismatches or missing language modules.

All Mod Cons

As a modern language, Go includes a bunch of built-ins that are well-suited to our typical programming projects. Support for JSON, XML and especially HTTP are excellent.  Sure, Python has urllib, urllib2, httplib, httplib2 (what was I saying about “more than one way to do it”?), but everyone really wants to use Kenneth Reitz’s requests library.   Go’s built-in HTTP support feels kinda like that, and even includes a template engine for text and HTML — perhaps obviating the need to bikeshed about Mako, Jinja2, Chameleon, et al.

Format, Dammit!

I’m
definitely not a fan of the Perl-esque “there’s more than one way to do
it” philosophy; there should be an obvious “right” way to do something,
a preferred idiom.  This applies not only to language constructs and
features, but something as prosaic as code format.  In Python, we had PEP-8 to guide us; it makes looking at other people’s code easier.
I
actually like Go’s fascist approach to code formatting: there’s only
one way to do it.  The “go fmt” tool does it for you, so everyone’s code
has the same look-n-feel.  Is this simply a way of destroying coders’
inner Jackson Pollock? I don’t think so: I think it eliminates a major bikeshed that slows down programming teams. 

Testing and Vetting

Like other modern languages, Go emphasizes automated testing and provides tools to take away any excuses.  Charles and Reed whipped up this git pre-push hook that we’re using to check for improperly formatted files, vets it (like other languages’ “lint”), and then run our tests. It keeps us honest, with no extra work on our part.
#!/bin/bash
set -e
unformatted=$(goimports -l -e .)
if [ -n "$unformatted" ]; then
    echo >&2 "Go files must be formatted with goimports. Please run:"
    for filename in $unformatted; do
        echo >&2 "goimports -w $PWD/$filename"
    done
    exit 1
fi
echo "running go vet..."
go vet ./...
echo "...OK"
echo "running go test..."
go test -race ./...
echo "...OK"

Tools for Editors

Of course decent code editors now have syntax highlighting and such for Go.  Lots of folks build other Go tools like “go fmt” into their code editor experience.  There’s lots of docs for doing documentation lookup, snippet inclusion, auto-completion, etc.  A casual look turns up plenty of ways to build these into Vim, Emacs, Sublime, as well as larger IDEs. 
As I get into it, I’m adding these to my Emacs configuration, and will blog some notes about what I’ve done in a follow-up post.

It’s not Perfect

First, the name. It’s a nit, I know, but I feel like I’ve developed a stutter: every time I want to search for or tag something about Go, I have to say “go golang …”.
I expect to miss Python’s “REPL” a lot; that allowed me to try things out and experiment. It’s a comfy chair for code exploration. The Go Playground kinda helps here, so maybe I’ll be fine with that.
In Python, I’ve become used to a few solid of web application frameworks. They handle boring stuff that I don’t want to implement myself, that’s foundational to the real application I’m trying to build.  As much as I can tell, Go has a number of frameworks too, but none seems to be emerging as a clear winner, and I’m not seeing the features that I’d like to rely on: sessions, fine-grained permission control, basic user management and password reset, etc.  I hope I’m just missing this due to my own ignorance because I don’t want to waste time building those each time, or have to worry about getting access control policies right (security’s hard).
Perhaps it’s just early times, but I’m not having a lot of love for Go documentation.  Yeah, there’s tons of API docs, but I don’t learn best from auto-generated reference docs.  As a Go newbie, I need something that explains the hows and whys, the idioms.  I’d really like a “Dive into Go” like the excellent Mark Pilgrim “Dive Into …” series did for Python, HTML5; something like that anyway.

Hot or Not?

My first attempt at playing with Go was surprisingly gratifying: I took a
brochure-ware website and reimplemented it in Go.  It took under a day, with no outside help, and a defiance against getting smart ahead of time.  Probably not the
most idiomatic Go, since I hadn’t read any docs beforehand.  But it
used the HTTP routing and HTML templating, and — since this was deployed
on GAE — the App Engine datastore for persistence. It was pleasant and the code seems pretty readable, obvious even.

Despite some complaints and the natural productivity hit I’m experiencing with using a new (to me) language, I’m rather liking Go. Lots of it just makes so much sense, in the “duh, why haven’t we always done it?” way.


I can only hope that the Go community likes Belgian beer and single malt whisky as much as the Python community. 🙂