Skip to main content

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.

Comments

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?
Unknown 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.
Anonymous 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.
Alessandro said…
I'm curious, how do you block in Go?
Alessandro said…
I'm curious, how do you block in Go?
Anonymous 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.
Anonymous 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.
Anonymous 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?
Steven Stringer said…
Great post. I'm starting out in go and loving it.
Sujai said…
Thanks for the wonderful post, I'm starting out in Go as well and loving it

Popular posts from this blog

Your last name contains invalid characters

My last name is "Graham-Cumming". But here's a typical form response when I enter it:


Does the web site have any idea how rude it is to claim that my last name contains invalid characters? Clearly not. What they actually meant is: our web site will not accept that hyphen in your last name. But do they say that? No, of course not. They decide to shove in my face the claim that there's something wrong with my name.

There's nothing wrong with my name, just as there's nothing wrong with someone whose first name is Jean-Marie, or someone whose last name is O'Reilly.

What is wrong is that way this is being handled. If the system can't cope with non-letters and spaces it needs to say that. How about the following error message:

Our system is unable to process last names that contain non-letters, please replace them with spaces.

Don't blame me for having a last name that your system doesn't like, whose fault is that? Saying "Your last name …

All the symmetrical watch faces (and code to generate them)

If you ever look at pictures of clocks and watches in advertising they are set to roughly 10:10 which is meant to be the most attractive (smiling!) position for the hands. They are actually set to 10:09.14 if the hands are truly symmetrical. CC BY 2.0image by Shinji
I wanted to know what all the possible symmetrical watch faces are and so I wrote some code using Processing. Here's the output (there's one watch face missing, 00:00 or 12:00, because it's very boring):



The key to writing this is to figure out the relationship between the hour and minute hands when the watch face is symmetrical. In an hour the minute hand moves through 360° and the hour hand moves through 30° (12 hours are shown on the watch face and 360/12 = 30).
The core loop inside the program is this:   for (int h = 0; h <= 12; h++) {
    float m = (360-30*float(h))*2/13;
    int s = round(60*(m-floor(m)));
    int col = h%6;
    int row = floor(h/6);
    draw_clock((r+f)*(2*col+1), (r+f)*(row*2+1), r, h, floor(m…

The Elevator Button Problem

User interface design is hard. It's hard because people perceive apparently simple things very differently. For example, take a look at this interface to an elevator:


From flickr

Now imagine the following situation. You are on the third floor of this building and you wish to go to the tenth. The elevator is on the fifth floor and there's an indicator that tells you where it is. Which button do you press?

Most people probably say: "press up" since they want to go up. Not long ago I watched someone do the opposite and questioned them about their behavior. They said: "well the elevator is on the fifth floor and I am on the third, so I want it to come down to me".

Much can be learnt about the design of user interfaces by considering this, apparently, simple interface. If you think about the elevator button problem you'll find that something so simple has hidden depths. How do people learn about elevator calling? What's the right amount of informati…