Last Thursday (July 22nd, 2010) Rob Pike, a Principal Engineer at Google, gave a talk at the O’Reilly Open Source conference. In this talk he stated that established languages such as C++ and Java are too complex and not adequately suited for today’s computing environments. He then proceeded with some criticism of dynamically typed languages (that I share) and finally ended up plugging the Go language (which he co-developed) as a solution to the problem.
Now, Rob Pike is not nobody (in addition to being a Google principle engineer he has C and Unix credentials), plus the Go language has the Google brand name on it, so I thought it would be a good idea to check it out….
The Go programming language is described on the website as a language geared towards system programming. That is to say, it is a new(ish), general purpose programming language developed internally at Google to scratch an itch some of their developers had and they then decided to open source it.
Evidently, judging from Rob Pike’s talk at O’Reilly, it is also intended to be a simpler alternative to C++ and Java and a more robust alternative to dynamically typed languages such as Ruby, Python and such. It is this claim that I felt was particularly intriguing, so I took a look at the language this evening by reading through the language spec and briefly glancing at the tutorials.
Well, let’s address the great big elephant in the room immediately: it would seem that “simpler alternative” is Google-speak (or Pike-speak) for “forty five years old”. It’s had a spit-polish plus language features and libraries added, but there’s no way around it — Go is a rehash of the C programming language with some Pascal thrown in for good measure. Not surprising of course, given Rob’s background, but perhaps not the great linguistic revolution you would have expected.
Just to reassure you all, I’m not exaggerating: Go is essentially C, including structs, pointers and reams of different (un)signed int types. It even includes everyone’s favorite cross-platform language feature: numeric types whose size is architecture-dependent.
That’s not to say that some improvements have not been made to cover up some of the glaring problems that made C and C++ hard to handle: extern is gone as a concept, as is pointer arithmetic. Plus Go has a type definition feature, so you don’t need macro’s anymore. Also, Go has some more built-in types (such as complex numbers), support for Unicode and it can insert semicolons where needed and has both escaped and unescaped strings (both borrowed from Bourne Shell). And it places the type behind the identifier instead of in front and uses := as an assignment to distinguish from equality (borrowing from Pascal).
Back from the dead
Nevertheless, not all is well with the world. Like it’s ancestors Go still relies on an ability to export named entities (including variables), meaning you can get into the global variable mess. And guess what’s back from the dead: the goto statement, in its full and glorious horror.
So what else is new?
At the core of it, Go is a component-based language. It’s main architectural feature for this is the package, which isn’t much like Java but rather borrows from the Unit found in Turbo Pascal: a collection of exported types and identifiers, with hidden implementations. Packages serve as libraries in the language and are the main strength and source of language functionality.
In the spirit of “this is your grandfather’s technology”, Go is not an object-oriented language. Instead it is fully procedural and uses the abstract data type as its main means of abstraction. Admittedly, this is a good combination with the Unit-like library. The ADT concept has been bolstered with real language support to keep ADT functions and data structures together though. Even though the main data structures are C-style structs, the language includes the concept of a method (which is a function that is sort of legoed into a data type, creating the effect of putting a function pointer into a struct in C). Methods directly associate a callable code block with a data structure, so it’s sort of like adding real behavior to your basic data type. That’s a pretty good concession to OO thinking sure enough, but encapsulation beyond the package level and inheritance are still out.
The other major feature of the language is built-in concurrency modeled on Tony Hoare’s Communicating Sequential Processes. This is a brand of concurrency that is not based around the classic “multi-process, shared single memory” model but around a “multi-process, multi-memory” model whereby processes are linked together by channels. Each process can “toss” values to another process over a channel (or “catch” values coming in across a channel). These operations block until succeeded, which allows for synchronization. The mechanism has been proven equally powerful as Dijkstra’s standard semaphore mechanism. This is once again a typical choice for someone with Rob Pike’s background as this mechanism is also included in the Bourne Shell in the form of named pipes. Of course in such a language it must also be easy to start threads or fork subprocesses and indeed this can be accomplished with the use of a single statement.
So what are we to make of this…
The Go programming language is an interesting combination of proven language features and program architectures. Rooted firmly in the Pascal/C/Bourne Shell era, it seems a bit of a museum of 1960’s language design ideas geared towards the hardware systems environment of that era’s dreams (and possibly today’s reality): heavily multiprocessed with the distinction between local and distributed processing disappeared into the background, using ADT and component-based modularity to achieve separation of concerns.
… except perhaps a bonfire?
And yet, I can’t say that I’m overly impressed with Go. Mostly I don’t see the point. Sure, its well-suited to the multiprocessing environment that we have nowadays. But its support for domain modeling and domain driven design is poor, based as it is on the ADT concept — a serious failing in a modern language if you ask me. And a language that isn’t architecture independent in a Cloud-based platform era? Come on… But most of all I don’t see the new language idea that is supposed to make this language better than all others. I don’t see a refreshing combination of functional and OO paradigms like Scala, or an “easily-typed shell over a large Java class library” like Groovy. I don’t really see what Google thinks it has accomplished with Go.
In addition to that, I don’t see proof for the claim of simplicity. Sure, it covers up the worst pointer-related problems in C/C++. Sure, multithreading is less verbose than it is in Java. But on the whole the language is no simpler than Java, as far as I’m concerned. I don’t like the lacking encapsulation, the poor man’s OSGi modularity, the way methods are tacked on to external data types rather than syntactically part of data structures. And I don’t think first-class lambda functions (popularly called closures) are all that special and I don’t think that having channels as a built-in language element is a great advantage over having them in a separate library (like C++ or Java do).
So what do I think of Go’s future? Well, it certainly has one major weapon in its arsenal: the Google logo, which still makes everything cool that it touches. So Go might get somewhere based on that. But on its own merits I can’t think of any reason to prefer it over another language.