Wednesday, July 04, 2012

Things I like about programming in Go

I recently wrote a blog post for CloudFlare about our use of Go. I thought it was worth following up with a bit more detail about why I like Go. In no particular order:

1. It's a fun language to write in

That's hard to justify because it's very personal. But to me Go has all the power of C, and all the fun of a scripting language. Go breaks Ousterhout's Dichotomy. Things like slices make doing the sorts of fast pointer-based things I used to do in C safe and fun.

And the fact that it's missing exceptions seems like a win because I much prefer dealing with errors when they occur.

Variable declaration, particularly using :=, means you get on with programming not doing a bunch of typing about types.

And, lastly, gofmt means a complete end to code formatting wars. There's one true way.

2. CSP

I was lucky enough to study at Oxford under Tony Hoare and so Hoare's Communicating Sequential Processes was an important part of the syllabus. And my doctoral thesis is all CSP and occam. CSP is incredibly simple and powerful: processes go ahead and run in parallel until they need to communicate at which point they synchronize on a communication. There's no shared memory.

Go takes the ideas of CSP (and of Dijkstra's Guarded Commands) and replaces Hoare's synchronization with channel-based communication (with synchronization) (this is actually very, very similar to occam). This does two things: it means the synchronization is part of the language (and not something that you do by calling synchronization functions) and that sharing by communication (instead of sharing memory) is natural.

Coupling that with goroutines (which are very, very lightweight) means that it's trivial to write concurrent programs without worrying about the usual headaches of threading. As long as communication between the routines is solely done through channels it just works.

3. It's ok to block

Recently some languages/frameworks (notably node.js) have tried to solve performance problems by making extensive use of callbacks (in the form of anonymous functions) so that whenever a system call is in progress the code can disappear off and do work. I think this makes code seriously ugly.

The ugliness comes from two things. Firstly, you're forced to write code in what seems like a backwards manner constantly writing callbacks that will do things when some other things are done. And secondly, rather than solving the problem at hand node.js forces the programmer to do extra work all the time. That's a sort of programmer busy work that's essentially useless, since computers should be worrying about those sorts of problems, and programmers should be worried about writing functionality.

Go on the other hand allows you to simply block. Create a goroutine to do the work and just do a system call and when it finishes your goroutine can carry on. No need to worry about any underlying implementation.

4. Static duck typing

Go dispenses with type hierarchies and has a simple notion of an interface which means you get something close to duck typing while getting static, at compile time type safety. This one feature alone means that it feels like a scripting language.

5. Rich library

The Go library is incredibly rich. Just go look at it. All those library packages are well thought out, clearly documented and performant. Because the library is open source it's easy to dig in and read the code (which is all formatted with gofmt) and see precisely what it does.

These libraries are in real-world use at companies like Heroku, Google, StatHat, SmugMug and more. They are ready for prime time.

6. Instant builds

I started a company to speed up builds (particularly for C/C++) because build time is an absolute productivity killer for any developer. And slow builds are one of the things that distinguish scripting and system languages. Go completely does away with that by cleverly handling the dependency problem in the compiler making all builds lighting fast.

They are so fast the the Go Playground compiles and runs code while you wait.

7. No free

The language is garbage-collected meaning there are no specific memory allocation/deallocation primitives. I used to love doing memory management because it felt like I was doing really useful work. Having seen Go in action I now think it was total busy work.

Aside

I'm sure some people reading this are going to say "But language FrobBub has had NoduleFoos for years cretin!".

You know what, I don't care.

What Go has done is brought together a set of features that make it compact, fast, readable, expressive and fun to program in.  I've programmed seriously in tons of languages (both functional and not) and Go is the most fun I've had in a long time.

If you enjoyed this blog post, you might enjoy my travel book for people interested in science and technology: The Geek Atlas. Signed copies of The Geek Atlas are available.

9 Comments:

Blogger Jason Catena said...

If you had it to do over, would you have written Accelerator (or Commander) in Go? Would you have implemented Commander's property hierarchy as an actual filesystem?

5:48 PM  
Blogger Joseph Marshall said...

My biggest problems with go are the lack of stability on anything other than linux x86_64 (maybe that's changed recently?) and its GC.

At my day job I do graphics programming on Android. Dalvik's GC kills when trying to get a steady 60fps. I can't speak for go's GC but for me a very important part of an environment is how well I can rely on making the VSync.

I've recently been trying out Mozilla's Rust. So far I'm really liking their approach to, among many other things, memory management.

6:23 PM  
Blogger Kai said...

Add Tinkercad.com to the list of things written in Go. It's actually a fairly complicated distributed system, we run a hundred instances of roughly a dozen different server types to make the web CAD work. There is an older Google tech talk on YouTube if you are interested in the details.

@Joseph: My apologies for the Go ARM compiler, I wrote the original version. Ken eventually fixed it up so the end result should be much more stable nowadays. There is no need to use the GC for performance critical memory management, just use arenas and the unsafe package. I've done some Go ARM coding on devices with just a few tens of kB of memory, you can certainly do really performant code using it.

6:40 PM  
Blogger Alessandro said...

I'm curious, how do you block in Go?

9:05 PM  
Blogger Alessandro said...

I'm curious, how do you block in Go?

9:08 PM  
Blogger Uriel DeLarge said...

> Joseph Marshall

Go allows you to control memory layout which makes it easier to control the load you put on the GC, and even avoid it almost completely if you are careful enough.

There have been considerable improvements to the GC after Go1, and more are in the works.

11:54 PM  
Blogger Uriel DeLarge said...

> Joseph Marshall

Go allows you to control memory layout which makes it easier to control the load you put on the GC, and even avoid it almost completely if you are careful enough.

There have been considerable improvements to the GC after Go1, and more are in the works.

11:54 PM  
OpenID projectshave said...

About 20 years ago I worked on a proprietary language based on Milner's CCS. We used the Edinburgh Concurrency Workbench to verify the programs were free of deadlocks and such. I was thinking something similar could be done with Go. Could one extract the CSP logic from a Go program and prove it is correct with a theorem prover?

2:18 AM  
Blogger Steven Stringer said...

Great post. I'm starting out in go and loving it.

8:52 AM  

Post a Comment

Links to this post:

Create a Link

<< Home