TRANSCODE Explorations into the Code Transcendental.

Should you Go?

Should You Go?

2012-080-06 [DRAFT]

Preface

I’ve been working on a (somewhat esoteric) IME for Android over that last couple of years and recently I decided to automate part of my design process. I had been manually evaluating keyboard layouts for ergonomic quality. After expending so much time and energy into evaluating one layout after another, trying to ascertain which is optimal in my mind without coming to any firm conclusion, I decided something had to give. And so I did what a coder does best: I wrote a program to figure it out for me. The idea was straight forward. I would codify the principles by which an ergonomic layout is to be judged, assign a score to each of those principles, and then have the computer shuffle through every permutation to find the one with the highest score.

Thanks to its elegance and my high fluency in Ruby, I was able to whip out an initial working program in a few hours, and by the end of the day I was getting useful results. Unfortunately there was a problem. It was Way Too Slow. The first culprit, it become clear, was that a brute force search wasn’t going to suffice. There were simply too many possibilities. To remedy that I added a simple genetic algorithm and seeded it with an initial population of layouts I already knew to be pretty good. That helped a lot, but it was still Way Too Slow. So then I decide to turn this new problem into an opportunity. And that’s where this story gets interesting…

Learning Go

I’ve been wanting to learn a new modern programming language for a while. Having a relatively small yet substantial problem to solve made for the perfect excuse. After doing some research on Go, Julia, Haskell, Erlang and Elixir –all languages I expected to offer me a nice bump in speed (wait, isn’t that just about any language compared to Ruby?) I narrowed my choices to Elixir and Go. I choose Elixir because it was a functional language but borrowed much of it’s syntax from Ruby. That would make the transition easier. And I choose Go because it was a lower-level language, potentially offering the greatest speed gain. I’ve always hated C and I will never endeavor to be proficient in it. But Go presents a much more approachable way to program that is fairly close to the metal like C. So I am pretty tickled by its prospects. I dived into the Elixir first, but I will save my thoughts on Elixir for a future post. The rest of this article will cover my initial thoughts on Go.

Initial Impression

If I were to sum things up as concisely as possible I would say this about Go: “The really good thing about Go is that there is so little to it. The really bad thing about Go is that there is so little to it.” That is very accurate. In Go, I had to write a function to scan an array of string for members. I stress “array of string”, because, you guessed it, one would have to write a completely separate function for array of int. Go has no general functions. Every function is type specific to its very bones. Many a questions on the golang-nuts mailing list ends with the post “There is no general solution…”. It really does seem crazy how many hoops one has to jump through to get things done. What would be a clear one-liner in Ruby, well, it will take at least a handful of lines in Go. In the future, I truly expect to hear old-time Go coders swapping legends about maintaining million lines of code. (Just like old times!)

But!!! (triple exclamation) There is a silver lining. As awful as all that sounds, the downright simplisticness(TM) of Go does have two really great benefits. First, there isn’t much to learn with respect to the language itself. It literally takes a day to learn the basic constructs and to get up and running at a pretty good clip. Secondly, because every itty-bitty routine must be coded there is hardly any doubt as to exactly what the code is doing and there is plenty of room for optimization all along the way. This is one of the things that makes Go code so fast. Granted it leaves room for a poor coder to write less than optimal code too, but Go Trusts You. On the whole the extreme simplicity of the language is a net positive.

Beyond that, coding in Go was fairly comfortable. The syntax is actually harder to read than it is write, as strange as that sounds. After writing Go code for just for a short while, it starts to feel very natural, which probably accounts for why I was able to write my program in just over a day, despite never having written a lick of Go before. In particular I have to give props to Go’s for loop construction. The whole for i, x := range anarray { ... } thing makes writing most loops a breeze.

Case-for-Visibility

One reason the code might be a little hard to read is Go’s use of function name capitalization to “export” a package’s public interface. There is a part of me that wants to agree with other that this is stroke of Genius. Many Rubyists feel the same about the capitalization of Class names. However, when ever I see capitalization being made significant in a language a little red flag goes off in the back of my head. Upon a more tempered consideration, it is perhaps easy to see why. The designers admit this is an issue for those who code in certain foreign languages. But they also say, “the case-for-visibility rule is unlikely to change however; it’s one of our favorite features of Go.” It would seem the designers might need a lesson on the Adrien Brody Rule. If it were only a convention it might be passable. But forcing it is really unacceptable for wider use as a global programming language. And personally, after the initial coolness wore off, I began to think it just looks bad. Alongside Go’s CamelCase convention (and you kind of have to do that once you require capitalization), you end up with somewhat ugly, “Visually Basic” looking code. Clearly they missed the Ruby memo: When it comes to readability, foo.make_something_good beats foo.MakeSomethingGood.

Project Structure

Another significant issue with Go is its standard project structure. Essentially it pushes the one giant workspace approach to development (see http://golang.org/doc/code.html). That might make sense for a software development house, but for other types of coders that is really not acceptable. I sometimes have projects where the code is just an auxiliary aspect. The project could have presentations, spreadsheets, word documents, etc. If there is code associated with the project it needs to reside alongside these other documents and not be handicapped for doing so. Currently the only way I see for doing this is to adjust the $GOPATH every time I work on such a project. No fun. Hopefully there is a better way yet too be discovered, or that the Go designers will eventually provide.

Debugging

From what I thus surmise about the tools provided for Go, I have only scratched the surface of what is available. But I can say that one the best things about working with Go were the very clear and directory error reports. By default, at least, Go doesn’t fill the screen with stack traces and code snippets. Rather is simply states the problem in plain English and give the file and line number where it arose. The clarity of the error messages made it very easy to correct every issue detected by the compiler.

Documentation

With regards to documentation, I have to give Go a push. What is available is still quite weak. However, given how new the language is, the current state of documentation is actually rather commendable. With its growing popularity, clearly this is a situation that will improve rapidly.

Einstein had a saying, “Everything should be made as simple as possible, but not simpler”. In some respects, such as the generics issue, Go has made things too simple. If Go’s designers ultimately find a way to support generics –and by all accounts they are at least open to the prospect, the language would become much more accessible. And some of this critique will be mitigated. But despite it’s over simplification, it beats the pants off the converse issue over complexification, which we too often find in other languages.

Go is the best new language to come along since I learned Ruby in 2002. I think anyone still coding C when it’s not absolutely necessary, is just a glutton for punishment. I highly recommend you Go, and Go now.