Some Initial Thoughts On Go

2016-06-03

Note: This post was originally published on medium

For the uninitiated, Go is a relatively new programming language that is being developed at Google. It's designed by some real heavy hitters including Rob Pike and Ken Thompson. Despite being new, it's already grown rapidly in popularity. Because of some projects I'm starting at work, I've begun to really actively look at Go. For the last month or so I've been reading all I can about the language and I want to present some of my initial thoughts.

Things I Really Like

Static Types

I love python. I love it to death. I wrote my first major web app using the Django web framework. But it's dynamic typing always bothered me. Maintaining large code bases is easier when you have static types, so I really think Go made the right choice here. I hate writing documentation, I'd just rather write "self-explanatory" code. Static types play a big role in helping me document my programs with the code itself.

Resource Management

When you consider the company backing Go, it becomes pretty clear what Go's intended application domain is: large scale web apps. In this domain, there really isn't a need for fine grained resource management. This no doubt influenced the decision to make Go garbage collected. Any performance degradation due to GC pauses will be far out-shadowed by blocks on I/O. We're writing web apps here folks, not working with the bare metal. There's no need for malloc and free. Let's just make life easy for ourselves and let the garbage collector take care of that nastiness for us.

Concurrency

I spent my undergrad and graduate school studying high performance computing (i.e. super-computers). Most of super computing comes down to just writing really fast concurrent programs, so I've seen a lot of models for achieving concurrency. I think concurrency is one place where Go really shines. Concurrent Sequential Processes are pretty easy to reason about (just think Unix Pipes). The notions of goroutines and channels obviate the need for a lot of the complexities around things like mutexes and semaphores. Goroutines remind me a lot of the coroutines in the tornado framework and the async and and await operations found in .NET and HACK. These features have been wildly successful in their respective domains, so I imagine they'll be great for Go as well. Easy-to-read, concurrent programs are hard to come by. But Go seems to have a found a good model for achieving this. Awesome.

Forcing Composition Over Inheritance

One of the biggest lessons I learned when I first joined the industry was to heavily prefer composition over inheritance. I've felt real pain as I've been backed into a corner due to inheritance hierarchies. Go just straight up doesn't allow for inheritance. It actually doesn't even have the notion of a Class (at least a the kind you might find in C++/Java/C#). Instead, Go just has structs and interfaces. The structs look similar to C structs and the interfaces look the same as they do in Java. A struct can then implement an interface. If you need the functionality of two different structs you can just create a composite struct using something called embedding. This feels really good. I'm excited to try this out.

Things I'm Not so Hot on

Non-Explicit Interfaces

Go doesn't require that a struct explicitly state that it implements an interface. All the struct has to do is have the methods required by an interface. The fact that interfaces are "implicitly satisfied" leads to some pretty nifty implications. But it comes at the cost of less "code as documentation". You can't just look at the definition of a struct and think "Ah, ok, so these are the things I can do with it".

No Generic Types

Initially it sounded like the language designers of Go didn't think it really needed generic types. They've since admitted that while generic types might be useful and may be added in the future, they still haven't found a good way to implement them in the language. This was almost a non-starter for me. I use Generics on a fairly regular basis when I'm doing Java programming and the thought of not having them in a modern language feels really really bad. I've already seen several algorithms that basically give up type information and operate on the type interface{} (Go's equivalent of a void*). I feel like I shouldn't have to give up my strong types just to write a generic data structure or algorithm.

Things I'm not Sure I Like or Dislike

Nullable Types

Probably one of the coolest features of languages like C# and Kotlin are the notion of nullable types. They can really help you get a handle on NullPointerExceptions. Go doesn't have this feature. That said, I'm not sure Go needs it. In most of the example Go I've been looking at, values are passed around, not pointers. I get the feeling NullPointerExceptions aren't really that big of a deal in Go. It just doesn't feel like they happen that often.

A Closing Note

I'm just beginning my foray into Go, so consider all of these thoughts preliminary. I'm working on semi-large personal project using Go and I'm starting to use it at work, so I should have a more solid opinion in a few months. Go has a lot of cool features that I wasn't able to mention here, so I strongly encourage you to at least check out the tour and see some of coolness for yourself.