Comments:"Why Go?"
Go was introduced on November 10th, 2009 as a new system programming language with quick build times. Go's excellent tooling, elegant concurrency model and unique approach to object-orientation has captivated the attention of developers from compiled and scripting languages alike.
“Go will be the server language of the future.” - Tobias Lütke, via TwitterIs there truth to Tobi's assertion? Before we can evaluate if Go is a panacea for modern web development, let's look at the trends, and consider what “the server language of future” should provide.
Real-Time Web
Ajax is so 2005.
Modern web applications provide real-time collaboration, with Trello (tech) and Asana (tech) being exemplary.
Some applications employ bolt-on solutions like Pusher. It works in a pinch, but feels analogous to a movie filmed in 3D vs. a movie with 3D added later.
“People's expectations of any product they use are set by the best experiences they have.” - Gene SmithGo should address the C10K problem, being able to maintain connections with thousands of users from a single instance, without exhausting available memory.
Cloud Computing
There is a distinction between the Cloud and the data centre underneath it. The cloud offers servers on-demand. Turn a knob to handle traffic, or let auto-scaling turn the knobs for you.
When scaling up or restarting instances, some virtual machines take a long, long, long time to come to life. Scripting languages often load and parse every line of code.
Go applications should launch quickly so our servers can handle increased demand. Idle instances, warmup requests, or other work arounds should be unnecessary.
Multicore Performance
Multicore went mainstream in 2004 with the first x86 dual-core chips. Even with data centres using commodity hardware, we should expect to see the number of cores double on a regular basis.
Go should be scalable. We should not need to rewrite our software to take advantage of additional cores.
Service Oriented Architecture
Whether or not your application is designed the SOA way, it's sure to be using a number of services: databases, caches, search and message queues.
SOA allows us to build or rebuild parts of our stack with different tools and languages. Is there this one Java library you really need? Make it an internal service.
Go should use asynchronous I/O so that our application can interact with any number of services without blocking web requests.
The Fat Client Renaissance
Between native mobile, HTML5 and Web Components, clients are doing more and servers are getting skinny. Modern apps are designed “API first”, built with the flexibility to target multiple clients.
Go shouldn't be tied to the frameworks of yore, but it should excel at writing APIs, with excellent support for JSON.
Report Card
So how does Go stack up? Given this is an article on the merits of Go, pretty well! Let's compare Go with our favourite scripting languages.
Async
Languages like Ruby and Python are afflicted by years of synchronous APIs. These APIs are off-limits when using evented programming based on coroutines.
“For a while, there will be the classic/legacy synchronous APIs and the new asynchronous APIs… merging them together eventually, and that will take years.” Guido van Rossum, Pycon 2013 KeynoteAt least Python is on the right path.
Node.js scores better, especially when coupled with a library like async.js.
The Go runtime ensures that any one goroutine isn't blocking the others. Code is written in a synchronous style while being fully non-blocking. There is no need for callbacks, so there is no “callback hell.” It's great for SOA!
Goroutines
What happens if we want to support thousands of connections and still take advantage of multicore? Simple. Use threads and use coroutines (Ruby calls them fibers, Python uses generators). Node.js has the Cluster module for multicore.
Go has one straightforward model. It multiplexes goroutines onto OS threads, and segmented stacks grow as needed. Go not only addresses the C10K problem, it blows past it! (C1000K)
And don't forget that Python and Ruby (MRI) still have the GIL/GVL. Go doesn't have an interpreter, nor a virtual machine, so no global lock. Multicore FTW!
Concurrency
Ruby's support for concurrency is left to users of the language:
“I don't consider myself as the concurrent guy, I don't think I can make the right decision for an actor library. I'd rather ask you guys to propose and discuss a future standard concurrency model.” - Yukihrio 'Matz' Matsumoto, Ruby Conf 2012 Q&ATo that end, Tony Arcieri's Celluloid steps in. But providing solid support for concurrency still requires involvement from the language/runtime.
Go channels provide a concurrency primitive comparable to the actors model.
Static Binaries
JVM-based languages are saddled with slow startup times. This doesn't just affect auto-scaling and server restarts. It can also be crippling in development.
Go applications compile quickly and launch immediately.
The Best of Both Worlds
So Go is ready for the future, but is it fun? In my opinion, yes!
Go provides type inference, hash maps (dictionaries), variable length arrays, methods on any user-defined type, and implicitly satisfied interfaces, all without diverging far from the familiar syntax and semantics of C-like languages.
“Go is closer in spirit to C than to any other language,” - Mark Summerfield, Programming in Go.It compiles quickly without makefiles, integrates with Git, etc. for distributed package management, and reformats code with gofmt
. Compilation makes a certain class of tests unnecessary, and code completion works really well via GoSublime or gocode
.
Performance critical code can be optimized without the need for C, so the fun doesn't need to end. And we have gophers! What could be more fun than that?
Go really does provide the best of dynamic and statically compiled languages. It's fun and efficient.
The best way to know if you'll like Go is to dive in and get some first-hand experience. So think up a small project and try it for yourself!
Reboot
It's very difficult to change a programming language once widely adopted. Even if the syntax/semantics could be hugely improved, too much code would break.
When I look at Ruby, I see C++11 in different clothes. Twenty years of cruft, and still adding features that nobody needs.
A new language is a fresh start.
Go is designed for clarity. It can be terse so long as the meaning is clear. In Go, ambiguity is avoided, even if it means increased verbosity.
“Go has been described by several engineers here as a WYSIWYG language. That is, the code does exactly what it says on the page.” - Peter Bourgon, Go at SoundCloudThe Go specification is easy to digest, it doesn't feel like mastery is beyond my reach. Simple, orthogonal concepts are highly valuable.
TL;DR
This talk touches on “Why Go” but also provides a quick introduction to who is behind the language and what Go code is like.
For more Go talks, I maintain a Vimeo channel and a YouTube playlist. Also, see the Go page on InfoQ and an interview with Robert Griesemer on Channel 9. Finally, the Go Wiki also provides a list of talks.
FAQ
Should I learn Go? I don't see many employment opportunities (in my city).
It's always good to learn and stretch your mind. Even if learning Go never lands you a job, you will have a new perspective when using other languages. For example, learning Go interfaces may give you a new appreciation for duck types in Python and Ruby.
Personally, I began learning Ruby on Rails over Christmas 2005, well before I could find any jobs using it. Now I've been employed for several years as a Rubyist.
Should I build my SaaS startup on Go?
This article is intended for programmers. Good developers think about the long-term. A startup has different goals: you need to run lean and prove out your idea.
Go's ecosystem is still relatively young. You may find a much quicker time-to-MVP using a framework like Ruby on Rails. But as always, it depends.
Is there a web framework like Rails or Django for Go?
At the time of this writing, Go doesn't have a full stack web application framework like Rails. Revel is as close as it gets to “full stack”.
I recommend the Gorilla Web Toolkit. It provides many of the facilities you would find in Sinatra or Flask. There is a good tutorial that starts out with the standard library and adopts Gorilla.
If you're using MongoDB for persistence, mgo is the package you're after.
When you first saw Go's syntax, did you like it?
Rubyists are often attached to syntax, whether snake case, single line ifs, or blocks.
Though initially quite neutral, I have come to like a number of things about Go's syntax:
- Indicating privacy with case is a concise way to export specific fields, and it's easy to distinguish between code using the public API vs. an internal API.
- I rather use
camelCase
throughout a web application than have camelCase for interacting with JavaScript libraries andsnake_case
elsewhere. - Initializing (nested) arrays/slices, maps and structs with the same composite literal syntax is actually really convenient.
- I love having
gofmt
hooked into to my save key. Automatic reformatting saves so much time.
Comment on Go+, Hacker News, reddit, or LinkedIn.
Published on 13 May 2013