Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

First Impressions of the Go Language

I recently got a chance to hang out with some very brilliant people and one of the guys mentioned how fond he was of Go, a programming language most commonly associated with Google. To be honest, the fact that it was “yet another thing that came out of Google” is exactly why I hadn’t played with it up until this point. I’d seen a few blog posts but skimmed them. This time, however, I decided to give Go a more fair shake and so I downloaded it and started hacking away. What happened next shocked even me.

I’m not a coding newb, but even I know that there’s a learning curve to each language and recently the learning curves have been getting steeper – Scala and Clojure come to mind, as well as some of the UI frameworks that aren’t languages, but they have language-sized learning curves (AngularJS is the 800 pound gorilla of learning curves). That’s why when I had ‘Hello World’ compiled and running in about 12 minutes after my first click on golang.org, I was shocked.

If you are unfamiliar with Go, it takes a little getting used to because at first glance it seems like a hodgepodge of some features you would never expect to see in the same language. Here’s a quick list that I found over on this blog post entitled Why Go?:

  • Asynchronous – We’re all about reactive programming these days and all the hip kids are building non-blocking, asynchronous code. In fact, if I hear one more Node.js zealot shout “it’s non-blocking” one more time, I will stab him in the face with a web socket. Go has these things called Goroutines that are lightweight async execution blocks and they have channels that make my inner Erlang and Akka fanboy giggle. Bottom line is you write synchronous-looking code but it’s non-blocking and there are no callbacks. Callback hell needs to be avoided at all costs.
  • Concurrency – Paired with the asynchronous support features and support for multi-core with channels is very appealing, especially considering some of the other aspects of the language (check out the next bullet, you’re going to crap yourself)
  • Static Binaries – Oh that’s right. There’s no JVM. There’s no VM of any kind. You don’t have to wait for a runtime to go dig through classpath garbage and dynamically load a hojillion JAR files. These are compilednative binaries. Remember way back in the good old days when you could just pass around and executable and that worked?? Yeah, I had almost forgotten those times as well.
  • Language Features – In addition to looking like C, having asynchronous, actor-like support for concurrency and parallel programming, it also has a lot of the goodies that people think you can only get from some of the newer JVM or functional languages  like type inference and my personal favorite, implicitly satisfied interfaces … wait wait.. it gets better… the implicitly satisfied interfaces are checked and satisfied at compile-time… I almost shed a tear when I saw that.
  • Privacy indicated via case, not keywords – Capital lettered members are exported, lowercase ones are not.
  • Imperative, object-oriented language – You’d think this is contradictory, but with Go it just seems to work. I was very skeptical until I started playing with it. Go doesn’t have classes, yet it supports message passing via methods, polymorphism, and namespacing. Crazy, right?
  • Multiple return values – The language looks like C, but you can invoke methods that return multiple values and it looks just like a Scala unapply syntax. Me likey.

So, I sat down and I downloaded Go and got it working and followed the advice of setting up the $GOPATH environment variable that pointed to a single root under which all of my Go code would reside. It felt a little awkward, but there seemed to be some method to the madness, specifically relating to the fact that Go can fetch its dependencies directly from Github and that it can resolve transitive dependencies without the need for a make file, maven, or sbt. Holy crap – compiling to a native binary without maven or sbt? That’s cause for celebration.

So, let’s get to the hello world? (You can get the instructions to download Go and set up “Hello World” from here at golang.org.

package main

import "fmt"

func main() {
  fmt.Printf("Hello world.\n")
}

When you issue a go install command at the command line, this compiles your Go code. It doesn’t just create a JAR file or a DLL file that will be interpreted (JIT or otherwise) by a runtime like the .NET CLR or the Java Virtual Machine, it creates a static standalone self-executing binary. Ah but you say Java can create executable JARs too, right? This isn’t the same, this is a native executable whereas an executable JAR is just a regular JAR with the JVM launching bootstrapped in.

When I first sat down and started reading the docs on Go, I had mixed feelings and still do. On the one hand, it feels like a step back in that some of it looks like old school C (don’t get me wrong, I love me some old school C) whereas other parts are amazingly terse yet ridiculously powerful (channels, goroutines, slices, transitive no-makefile dependency resolution). I don’t know yet what my final thoughts are, but I know that right now it is appealing to my love of the C language (I think Go is one of the most C-pure looking syntaxes I’ve seen in a long time) with my love of Erlang, the actor pattern, and asynchronous back-end programming.

This is just hello world. If you’ve read this blog before then you know the real test I have to put Go through in order to vet it as a language and I’ll be posting a series of blog posts on that soon. The real question I ask of any new language is this: Can I create a MUD with this language?

I’m about to find out – stay tuned!