Go (not the board game)

Nov 12, 2009 22:07


As you may have heard, a few days ago Google released a new programming language that they'd been developing for awhile. And by "they", I mean Rob Pike and Ken Thompson, both of whom were instrumental in the creation of Unix, its predecessors, and its successor. They also invented UTF-8. So, you know, there's some reason to pay attention.

As it happens, Pike gave a talk about what I suspect was the early parts of this project in a CS 343 class I took at Stanford as a grad student not that long ago.

If that's true, the answer for "why a new programming language?" is pretty clear; Google wanted something vaguely Python-like for writing their services in, but Python's famously horrible handling of concurrency and multithreading meant that it wasn't really appropriate for this.

Their new language, "Go", uses an old but reasonably well-proven mechanism for multithreaded communication. Despite being well-proven, it's almost never actually used, so in order to make this a proper language primitive they basically needed to write a new runtime from the ground up anyway. And once you do that, you might as well redesign the type system and so on and so forth, and pretty soon you have an entirely new language.

I figured that as something of a language geek I'd look at it and see what I could do with it. As it happened, I did have a project that could use it; while I was extracting karma information from Ultima IV save files (see my previous post for why I was doing that) I was using an ad-hoc Python one-liner for it:

struct.unpack("<8H", file("party.sav", "rb").read()[326:342])

Go advertised itself as being a systems programming language primarily, and binary unpacking is the sort of thing that one would normally use C for. Writing a somewhat more detailed savefile unpacker in Go might let me see more of the language in action.

It turns out that I didn't need a whole lot for this: the source code, u4scan.go, didn't really do much with the type system that a C struct couldn't handle just fine.

That said, I did get to see enough to like the type system a lot. I've never been much of a fan of OO or inheritance - my designs rely heavily on composition and what the Design Patterns guys would call the "strategy" pattern. Which is to say, my design sensibilities are much more in tune with ML or Haskell; I'm happier thinking of verbs that can act on various different nouns instead of thinking of nouns that carry verbs with them. It's all the same in the end (you get a 2D matrix of verbs and nouns), but it does influence what's easy to express.

Go takes Objective-C style "protocols" - types that are simply collections of the methods defined on an object - and pushes them as far as they will go. The result ends up bumping up against Haskell's typeclasses, which is about the strongest praise I can give. The type guarantees are much closer to Haskell's than ObjC's, though there's more declaration that needs to happen first. Go has some type inference, but it's not as good as the best inferrers. Nevertheless, it looks like an excellent combination of duck typing with static typing - ObjC's was far too easy to break.

Unlike Haskell, it's possible to break it in Go; the binary.Read function I used in the savegame scanner was able to unpack a binary file into nearly-arbitrary structures. (The requirement is simply that they be fixed-size and thus properly representative of a chunk of binary data.) Its reflection capabilities handle the rest. That made the meat of this project refreshingly easy. (I'd actually written some code using the unsafe portions of the language to convert floating-point numbers to and from their bitwise representations; it turns out that while it's not documented as being able to do this, the binary encoding package can handle floats fine.)

Go's ObjC-like use of protocols as the fundamental unit of typing extends to being able to add methods to arbitrary types (even primitives!) outside of their nominal definition, which means that I can organize things in the data-directed manner that I prefer.

As a professional C++ programmer, Go's declaration syntax gave me trouble until I realized that it was actually Pascal syntax with most of the punctuation removed.

So, yeah, as a language it's fairly nice. As a programming environment, however, there's almost no need for non-language-geeks to mess with it. It's simply not there yet. It's less there than Inform 7 was in its first public beta:
  • No foreign function interface. This would be less of an issue, but...
  • No I/O more complex than sockets and files. Interactive user interfaces aren't really in the cards.
  • No Windows compiler, since Google doesn't need one. All binaries are Linux and Mach-O (Mac OS X).
  • Even on Linux and Mac, the "real" compiler is a variant of the Plan 9 From Bell Labs compilers and so they don't use any runtime your home system will have; as a result, even Hello World is a 580KB binary and they only go up from there.

I suspect that if the gccgo subproject (which ties, unsurprisingly, into gcc's backend) gets some development, it will solve the last two problems neatly - if it works on gcc, it should work with MinGW as well.

But yeah, as it stands, fun to read about and maybe mess with, but unless you're actually part of the core development team, I can't see it being used for anything serious by anyone else for awhile yet.

development

Previous post Next post
Up