Go (The Programming Language)

go-logo-black

There’s a companion post to this piece in which I pretty much lay out my experience of programming languages. If you’d prefer to avoid reading through all that crap, I can summarize by repurposing one of my favorite lines from Barry Humphries (“I’m no orator, far from it, I’m an Australian politician.”) — I’m no systems programmer, far from it I’m a web developer. Go is explicitly a systems programming language — a tool for implementing web servers, not web sites. That said, like most programmers who live mainly in the world of high level / low performance languages, I would love to program in a lower level / higher performance language, if I didn’t feel it would get in the way. At first blush, Go looks like it might be the “Holy Grail” of computer languages — easy on the eye and wrist, readable, safe, and fast. Fast to compile, and fast at runtime.

What’s my taste in languages? Something like JavaScript that compiles to native binary and has easy access to system APIs. Unity’s JavaScript is pretty damn close — except for the system APIs part (it’s also missing many of my favorite bits of JavaScript, and not just the stuff that’s hard to write compilers for). Actually if I really had my druthers it would be JavaScript with strict declarations (var foo), optional strong typing (var foo: int), case-insensitive symbols, pascal’s := assignment, = a binary comparison operator, syntactic sugar for classic single inheritance, and ditch the freaking semicolon.

Of course, I am not — as I have already said — a systems programmer, so things like the value of concurrency haven’t really been driven home to me, and this is — apparently — one of Go’s key features.

Highlights

  • Clean syntax — it looks easy to learn, not too bad to read, and certainly easy to type. They seem to have managed to climb about as far out of the C swamp as is possible without alienating too many people (but I’m a lot less allergic to non-C syntaxes than most, so maybe not).
  • Explicit and implicit enforcement of Good Programming Style (via Gofmt in the former case, and clever syntactic tricks such as Uppercase identifiers are public, lowercase are private in the latter).
  • Compiler is smart enough to make some obvious ways of doing things that turn out to be serious bugs in C into correct idioms.
  • Safety is a design goal. (E.g. where in C you might pass a pointer to a buffer, in Go you pass an array “slice” of specified size. Loops use safely generated iterators, as in shiny but slow languages like Ruby.)
  • Very expressive (code is clear and concise, not much typing, but not too obscure — not as self-documenting as Obj-C though).
  • Orthogonality is a design goal.
  • Seems like a fairly small number of very powerful and general new “first class” concepts (e.g. the way interfaces work generalizes out both inheritance and (Java-style) interfaces, channels as a first class citizen are beautiful).
  • It really looks like fun — not hard work. Uncomplicated declarations mean less staring at a bunch of ampersands and asterisks to figure out WTF you’re looking at. Fast (and, I believe, simple) builds. It makes me want to start working on low level crap, like implementing decent regex… Makes me wonder how well Acumen would work if it were implemented as a custom web server, how much effort this would be, and how hard it would be to deploy…
  • What look like very fast compiles (and in his demo video (above) Pike recompiled more code in less time on a Macbook Air) — but then I’ve seen insanely fast C++ compiler demos that didn’t pan out to much in the Real World.
  • Really nice take on OO, especially interfaces (very elegant and powerful).
  • Almost all the things you want in a dynamic language — closures, reflection — in a compiled language.
  • Really, really nice support for concurrency and inter-process communication. Simple examples — that I could understand immediately — showed how you could break up tasks into huge numbers of goroutines, perform them out of order, and then obtain the results in the order you need to, without needing to perform mental gymnastics. (Lisp, etc., coders will of course point out that functional programming gives you these benefits as well in a simpler, cleaner way.) The 100k goroutine demo was pretty damn neat.

Lowlights

  • To quote a friend, “The syntax is crawling out of the C swamp”. So expect the usual nonsense — impenetrable code that people are proud of.
  • Concurrency is way better supported in the 6g, 8g, 5g version than the GCC (the first muxes goroutines into threads, the latter uses one thread per goroutine).
  • They promise radical GC, but right now it’s a promise (and no GC in the gcc version yet).
  • Pointers are still around (although, to be fair, largely avoidable, and reasonably clearly declared).
  • No debugger (yet), obviously very immature in many ways (weak regex, and see the point about GC, above).
  • The syntax seems a bit uncomfortably “open” (nothing but spaces where you are accustomed to seeing a colon, or something), but it’s a matter of familiarity I suppose.

Unknowns (at least to me)

  • How well does it compare to evolutionary improvements, such as Obj-C 2.0 (which is garbage-collected) combined with Grand Central Dispatch (for concurrency support and hardware abstraction, but at library rather than language level) and LLVM?
  • Will GC actually work as advertised?
  • Is someone going to step up and write a good cross-platform GUI library? (It doesn’t need to be native — it just needs to not suck — something that has conspicuously escaped both Java and Adobe.)
  • Will we have a reasonable deployment situation within — say — six months? E.g. will I be able to ship a binary that runs on Mac / Linux / Windows from a single source code base?
  • Will it get traction? There’s a lot of other interesting stuff around, albeit not so much targeting this specific audience (and it seems to me that if Go delivers it will appeal to a far broader audience than they’re targeting since it’s essentially very JavaScript / Python / PHP like with — what I think is — obviously bad stuff removed and better performance.

Conclusion

I’m not quite ready to jump on the Go bandwagon — I have some actual projects that have to ship to worry about — but it does look very, very attractive. More than any other “low level” language, it actually looks like fun to work with. The other newish language I’m attracted to — for quite different reasons — is Clojure. Because it lives on the Java VM it’s a lot more practical now than Go is likely to be for some time, and because it’s essentially “yet another Lisp” it affords a chance for me to really build some competence with a fundamentally novel (to me) programming paradigm. In a sense, Go is more attractive because it’s closer to my comfort zone — which speaks well for its chance of success. Clojure because of its conceptual novelty is almost guaranteed to remain obscure — the latest Lisp variant that Lisp adherents point to when complaining about <insert name of language people actually use here>. Time will tell.

  • Pingback: inconsequence › Programming Languages I’ve Learned()

  • Andrew Barry

    I had a look a Go and found it interesting – though I do think they made some wacky choices.

    eg they found trying to fit maps into their structure/pointer to structure concept map tricky – so they decided to create an entirely new type concept ‘reference types’ – which has a completely different constructor (make instead of new) – but which only applies for a handful of blessed concepts. Very strange.

    Some other stuff that they show in the tutorial also makes me scratch my head and wonder if they’ve really thought through all the consequences.

    On the bright side there’s a lot of good stuff there, but I do wonder at how well baked the language design is.

  • I wish they’d simply eliminate pointers — except, perhaps, for the specific purpose of dealing with external APIs. But this seems to be a religious issue.

    Perhaps the most interesting point to take from this is that there really seems to be an opening for a new language right now — concurrency is a huge hole in current mainstream languages, and a new language that takes all the new checklist features (closures, reflection, etc.) and provides first class support for parallelism has a shot at getting traction. This seems to be me to be good news since all C, C++, Java, and Obj-C are all showing their age.

  • Andrew

    Well, in the Go teams defense, they were designing a Systems language – and just couldn’t see themselves letting go of structures. But yes, I would have preferred they just went with references throughout as pretty well every recent language has done.

    I’m not sure that their parallelism support is really that much better – it still presumes shared memory and people doing the right thing – though channels are a better starting point than Java’s synchronized modifier.

  • Sean Case

    Rob Pike previously produced Acme, which is the Oberon UI ported to Plan9/Inferno/Unix. In many ways, Go is the Oberon language mixed with Rob Pike’s personal quirks.

  • There seem to be two options in computer languages — those shaped by a strong personality (let’s say Python or Oberon are examples) and those shaped by a committee (let’s say C++ or Java are examples).

    I’m not sure what Pike’s idiosyncrasies are, but it does seem like a pretty clean design. I also wonder if my angst over pointers is a bit unwarranted because idiomatic Go code wouldn’t use pointers much except to deal with the outside world. It does seem to me that unless you abandon pointers and bits in a language, you’re still essentially writing assembler — just inefficiently.

    Programming languages that rely on running on a VM so that they can “safely” play with bits etc. are just sidestepping the issue. Being tied to a VM is, ultimately, just as bad as being tied to a real machine.