I've completed my first foray into Go programming. For my first go (ha!), I've written a small program that tries to estimate the proportion of women vs men posting on Pinterest! Now that idea may sound totally random, and it is, but I had it a while back when there was a lot of chatter about pinterest being like digital crack for women! (though that there exists a site on the internet that is more popular with women is not in and of itself that surprising).

This program attempts to characterize one aspect of Pinterest's user base, by looking at the names of people pinning and liking pinned things on the pinterest front page. It is a nice little problem that involves downloading and parsing the pinterest front page, loading a list of women's and men's names and then counting up matches. The list of first names used for classification is from the US census site so will be biased to names popular in the states.

I'll show the program first and then give my initial impressions of Go. Two resources I found very useful in getting going with go (ha!) include the Go Tour and Effective Go.

The output of the program looks like this.


Results at 2012-08-12 18:32:14.146765 -0400 EDT Computed in 778.66ms

56 Women
0 Men
11 Unisex names: [ASHLEY PAUL SAMMY GAIL JORDAN LAUREN MARY RAY JEREMY JEREMY FRANCISCO]
12 Undetermined: [ONEEARUP RADMILA BAISCH BRENDA-STEVE KAILEIGH EVONASAURUS BUTTERFLY KIRSTY ELAAN @CINDY MARIYA @SIERRA]

Impressions

Go is imperative

Go definitely feels imperative, and wears its C heritage proudly. This comment is neither meant as a criticism or a praise, but it does distinguish Go from some of the other languages in this tour (who are more firmly in the OO or FP camp). The language shuns object orientation, though it has an interesting way of making functions on user defined types callable with a OO style dot syntax. For the most part though, it seems that most operations are just called as regular functions, with the caller passing in all operands and no explicit receiver.

At first it can be tricky to distinguish method calls from function calls (esp since packages names look like regular variables), and one of the first functions i wanted to use in this program, 'http.Get', is actually a method (it has some kind of default client as the receiver). But 'http' is just the package name so it looks like a regular function call. I can't quite explain how this particular method works, but I only mention it because it led to a few instances of trial and error in trying to call functions as if they were methods (which didn't work) before i finally got how the docs represent the differences between the two. Though overall this confusion didn't hinder me too much.

Functions are first class in Go and one can create anonymous functions and closures (though I didn't end up doing this), however some of the functions we are used to having in the standard lib of the functional languages, such as map, filter and reduce are not present. My current impression is that it is not possible to provide these as generic functions because Go does not have generics nor a type hierarchy. Thus one would have to define type specific versions of these functions if you want to have them available. Thus I just resort to C style iteration to do things like convert the lines of the file loaded in the loadFile function into names (with the new collection being defined outside of the iteration). However go does have a handy 'range' clause that can be used with 'for' to provide easy iteration of a collection type.

Go is Explicit

My impression is that Go code is very explicit about what it is doing, even if it does require a few more lines. The approach to error handling, which is returning error values from function calls and dealing with them on the spot, means you have to be immediately explicit about your plans to deal with the consequences of a function call.

You are also expected to be very deliberate in the variables you declare; unused imports, unused variables and return values cause are flagged as an error by the compiler and must be removed before continuing. I found this a tiny bit annoying (i probably would have preferred it to be a warning), but I can also appreciate that Go encourages you not to leave cruft around, if you want to ignore a return value of a function (functions can have multiple return values), you have to explicitly ignore it by assigning it to '_'. So in the code above if i am not using the index value returned by 'range' in my iteration I need to explicitly state so.

Go also has an explicit style, this is well embodied in gofmt, a program provided with the go distribution that formats your code in 'the one true way'. I like this idea and happen to like its style as well.

Go is Terse

Go is terse but not overly so (see Go is explicit), I like this, it is not a particularly ceremonial language and the end result feels pretty clear and readable. The type inference is quite handy and in a simple program like this the types completely got out of my way (yet the program is compiled and type checked!).

I found go api documentation can be a bit terse as well, though I'm also getting used to the conventions and where to look for things as well so that is getting a bit better over time.

Go is Young

Go just recently hit 1.0, though it has been around for a little while. But this impression is because I found that the longest part of writing this program was finding a html parser library that took css selectors (so that i wouldn't have to to do SAX style parsing for this little script). I found one that worked, though it seems to be somewhat incomplete. Now this should be taken with a large grain of salt, I've written one Go program that happened to need something in this area and i didn't see that much coverage in library support.

Overall

Overall I enjoyed writing this program, though I do miss generic collection functions and lack of generics means there isn't a generic concat function for slices. Go compilation is really fast, so running this program in development was very much like running an interpreted script.