I tried go out about a week ago. Despite being somewhat of a polyglot in university, I've really settled into being mostly a Python programmer the last 5 years. I wanted to break that funk with something that would complement my Python experience. That the timing coincided with the official release of go1 was a happy accident.

I had attempted to use one of the initial public releases, but trying go out a second time was a real eye opener. Despite being a statically typed language that compiles to binary, and the horrors of C and C++ that this brings to mind, the go language and toolchain is refreshingly modern.

Go features language-level package semantics, an enormous improvement on C/C++ style preprocessor messes and link-time confusion. There is an import keyword which will look on your path for packages, and a de-facto standard on how to organize these packages, which can be split into one or more files.

To get new packages, there is an pip/rvm/npm style go get command which can download packages from various code hosting sites and various repository types. The path you use to install a package, eg. go get launchpad.net/mgo, is the same path you use when you go to import the package in your code.

To build a binary, there is a go build command, which takes a file with the main package as an argument, and builds it. No makefiles, no tangled ball of XML build scripts, and in my short experience, very little problems.

The language itself is quite nice. The channel and goroutine abstractions seem amazingly powerful, and although I missed Haskell style type classes, the type inference and powerful interface{} notions seem to make up for the lack of both those and, surprisingly, generics. There is an impressive number of high class batteries included in the standard library, sane built-in strings and container types, and run-time reflection which allows library writers to reduce the burden of tasks that can cause pain in many static languages, like serialization.

Though the language is incredibly ergonomic, there are some rough edges. I can't figure out why the classic C-style for i:=0; i < x; i++ { ... } for loop was kept rather than creating a more readable and less error-prone shorthand using the iterating range keyword and Haskell/ruby style number ranges. In the name of explicitness and safety, no implicit type conversions are done at all, which means that passing around integers of slightly different sizes or shapes (unsigned v signed) can induce a cast of thousands feel, though there might yet be a way to use interfaces to dodge this. The languages uses javascript-style auto-semicolons, deceptively different from Python's statement termination, and although it doesn't cause many problems, it feels a bit wrong. Finally, while auto-semicolons ruins any potential brace-style flamewars, go fmt uses tabs by default, which is decidedly the wrong choice!

Despite the few gripes, I've really enjoyed my time with the language so far. I started out solving project euler problems, where the language was fast enough to brute force many problems, but high level enough to still use my Python brain to to implement algorithms. After feeling like I was reaching the limits of that introductory phase, I decided to write this very blog in go to figure out what it's like to write some "real" software in it.

And it's quite pleasant.

Apr 2 2012