Monday, November 15, 2010

Go: first impressions

Starting about a week ago, I've taken it upon myself to learn a new programming language: Go. This marks the first time in about six years that I've attempted to learn another language. Now that I'm about one week into the process, I've decided to describe here some of my first impressions.

Go is intended to be something of a C replacement. This I find interesting because I am, above all else, a C programmer. I am one of those guys who codes in C not just when I'm paid to do so but when, on those rare occasions, I do something “for myself” and want to make something that lasts, something that survives endless maintenance. It's not that C is the best language for this; rather, it's just that it's the best language for me, the one I think in most readily. Thus, all of my first impressions of Go are cast from the point of view of a C guy. Pardon the pun.

My method for learning Go has, so far, entailed reading through the documentation on the official website while working on making a simulator for the Acquire board game. Acquire, for those who don't know (and you should be ashamed!), is kinda like Monopoly in that it involves real estate trading and the goal of making money. My goal with the simulator is eventually to experiment with writing AIs for the game. I figure this is a good project in that it's non-trivial but affords itself to a highly irregular schedule when it comes to personal coding time. It also serves as a vehicle for learning Go.

One of Go's “guiding principles”, according to the FAQ, is to cut down on bookkeeping—those mundane, repetitive tasks in each language that end up being done for every non-trivial program. Here's the excerpt from the FAQ.

Programming today involves too much bookkeeping, repetition, and clerical work. As Dick Gabriel says, “Old programs read like quiet conversations between a well-spoken research worker and a well-studied mechanical colleague, not as a debate with a compiler. Who'd have guessed sophistication bought such noise?” The sophistication is worthwhile—no one wants to go back to the old languages—but can it be more quietly achieved?

In C, for example, any sufficiently sophisticated program ends up requiring a lot of work in: managing header files, memory management (even when no clever tricks are being employed and everything is by rote), and defining data structures. There's no way around this; it's an emergent property of the language.

My first impression of Go is that it does indeed live up to its guiding principle by reducing bookkeeping while maintaining flexibility and expressiveness. However, this is a pretty abstract and subjective point. Here are some more succinct, concrete impressions.

  • A lot of Go's syntax is backwards. Or at least it seems backwards after being firmly ingrained with C's arbitrary way of doing it.

    C Go
    int i;
    int *p, *q;
    int a[10];
    char const *s = "Hello, world.";
    char const *t = "Goodbye.";
    var i int
    var p, q *int
    var a [10]int
    var s string = "Hello, world."
    t := "Goodbye."
    typedef struct {
        int a;
        float b;
        char *c;
    } T;
    type T struct {
        a int
        b float
        c string
    }
    int foo(int a) {
        return a + 1;
    }
    func foo(a int) int {
        return a + 1
    }

    The above table illustrates the “backwards-ness” of Go. Of course, the order of the lexemes in, say, a declaration shouldn't affect a programmer's ability to organize his thoughts and solve problems, but after spending more than half my life in the C family of languages, such a change took some extra time for me to get use to. Like, an hour or two.

  • Go programs do indeed compile quickly, as advertised. Also, the compiler's error messages are meaningful and obvious.

  • Go doesn't have a while loop. The only looping constructs are for and goto (and the latter should never be used for looping, IMO). I'm not a fan of this because for years now I've used while to designate a “loop which does not have a set number of iterations known before the loop begins its first iteration.” Yes, I realize that while and for are basically the same thing in C, but in that language it's nice to choose the loop construct to connote further information to future maintainers.

  • Like many other modern languages, Go uses packages to modularize code. One trick I've never seen until Go is how the language determines whether a symbol is public or private based on the capitalization of the first letter of the symbol. So, for example, foo is private to its package, and Foo is public. This, along with the “opening braces go on the same line as the if and for”, makes it obvious that Go is trying to enforce a particular coding style. I'm not sure how I feel about this. I see the pros and cons.

  • Go's slices make a lot of sense and seem especially practical. Part of the extra bookkeeping in C is how most arrays require some sort of length and/or capacity meta-variable(s) kept in sync with the array. Go's slices are basically like array pointers that keep track of length and capacity automatically without adding the overhead that other higher-level languages typically add to array/sequence types, like smart insertion and dynamic reallocation. I'm interested in Go as a C replacement, not as a yet-another-great-prototyping-language, like Python.

  • I'm looking forward to using Go's panic and recover. The error-handling scheme provided by these two keywords appears to be just the right amount of structure to retain the simplicity and efficiency of a goto drain in C without all the arbitrariness and bloat of full exception handling.

All in all, after spending ten or so hours working with Go, I generally find my initial negative reactions, like with the “backwards-ness” of the syntax or the semi-forced coding style, to diminish while my appreciation of Go's power and elegance increase. My overall initial impression of the language is that it holds a lot of promise for doing what C does, better.

3 comments:

Anonymous said...

You had me at Acquire.
Way better than Monopoly.

silverfunk said...

Damn it Craig! I just started getting back into Python and now you are making me curious about Go. Up to this point the only thing I knew about Go was the controversy surrounding it's name when Google released it and there was already a language out there with that name.

Craig Brandenburg said...

Anonymous— Indeed. Laura is wanting to schedule an Acquire night soon. Not a game night. An Acquire night.

Silverfunk— For what it's worth, I'd say Python is more valuable now than Go. Go, as far as I can tell, is a newer, upgraded C. Python is (almost) a one-stop get-things-done-quick language and can change your life. It let me forget Perl.