Go, or as its easily google-able moniker, Golang, is a typed systems programming language created by Google. It was designed to be in the vein of C/C++ with Garbage Collection, simpler to read and write unlike C++, strong opinions about how code should be built and strong primitives to enable effective concurrency. It was originally designed as a thought experiment between Robert Griesemer (V8 engine, Google Distributed File System), Rob Pike (Unix Team) and Ken Thompson (B Programming Language, c predecessor).
There’s a lot of information and blogs about peoples experience with Go and I’ll link to a few of those at the end of this blog. I’ve been dabbling with Golang this last year for little side projects and a lot for the sake of learning. Coming from what most to be considered an somewhat embarrassingly long stint of doing PHP development for 4 years, it very quickly became obvious why there’s a lot of benefit to the choices made in Golang’s direction. I’ve also used Node the last 2 years for nearly all my side projects/backend work, java + objective-C for my mobile work and a bit of ruby, python and bash for scripting when it’s appropriate. For me Golang combines all the best elements of these languages, with an excellent community, build tools, it solves a bunch of problems in it’s inherent design and creates new ways to solve problems with its concurency options. I’ve been using it to build a few API’s and tools, and started toying with using some openGL bindings to make some little 2D games.
I wanted to share my thoughts on this with the larger dev community and hopefully spur on some discussions and even for a few people to dive in and try their hand at the language.
What Golang is all about:
- It is a statically typed, fast compiled language designed for modern development.
- Produces binary executables, like c++
- Powerful at Concurrency with inbuilt primitives and features to allow systems to be built to scale and effectively use the computing power available.
- Simple but Opinionated
- Empowered by the open source community; all users are encouraged to put their go projects on github.com when setting up their environment
- Automatic type inference (similiar to dynamic languages, var x int =3 or x := 3 or y := “James” are all valid)
- Automatic documentation. Like JDoc or PHPDoc, but no comments required, and even no commands. You can automatically have your code documented at the same level of quality as the standard library and inbuilt golang API’s.
- Strict compilation checking, unused packages and variables will prevent compilation.
- Strong standard library
- Awesome at building API’s/backend
- Cross platform (runs on linux/mac/windows. Currently has experimental mobile support. You can write an opengl program that can run on iOS/Android natively in Go1.5).
- Useful tools for code linting, code generation, building, testing, etc.
What Go doesn’t have:
- Classes ( * SHOCKED EXPRESSION *) — Golang has Structs, and struct functions, but there is deliberately no tradtional class structure or inheritance. Objects follow an Interface simply by having the correct function
- Generics. This is divisive to newcomers, but decisions made to build fast and smart binaries, no generic functions exist. This means if you have an getArea(number) function, you must have a getFloatArea(float) and getIntArea(int) if you wish to cover multipe types. Note that interfaces will allow alternatives to sidestep this issue with still some extra code but better organsation.
- Full memory control (due to garbage collection system)
- Vendoring is still early and can be enabled via an experimental flag. You can pull packages but updating them independantly; there are some community tools but I would expect something like a package.json to be added in the next release of Golang.
Why should developers care about Golang?
- Golang combines a clean, fast, typed language that is particularly strong for web development and has built into its ethos and community one very clear message: You don’t need a web development framework! The standard library provides everything you need to build a web server, do routing, html templates, file serving, res/req handling, databases, etc..
- It is very opinionated about how code should be written. For example the default linting tool decides exactly where there should be new lines (no more than one additional between function, etc.), automatically formatting brackets; code will not execute if you start your curly brace on a new line, there are no semi-colons due to the insistence on this rule. This means code is very readable, code can be easily worked on between teams and people can easily move between projects and be effective.
- Compilation is very fast (usually a second or two), and produces a single binary. This means in terms of artefact handling for deployment you only need to push a new binary and run it. There are currently MANY tools to enable application server orchestration (Puppet, Docker and the like), because a traditional Java Application might take someone half a day to setup just to run a hello world on a server. When Atlassian can to talk to us about how Docker enables their developers to setup their code in an hour instead of a day or two, this to me speaks to how languages like Java which is common in many places for reliable web app’s and API builds have some many pieces holding it together to be able to run. The web server, the build tool, the framework, the framework build tools, the dozens of libraries available to get core usage of the tools, testing tools… You’re getting a picture here. It’s big, i’ts clunky and we’re investing huge amounts of effort into learning orchestration tools because the fundamental tools we’re using to code and build web apps and api’s are crap.
- Whilst “The Cloud” has enabled us to quickly build, clone and dynamically add servers to handle load of performant web applications, it often ends up with people horizontally scaling to cater for often poor performing applications. 10 applications servers to run a simple web app because peak loads require it is a very expensive cost to customers. Using a typed compiled language gives huge benefits in this domain. There’s a great article from the creators of Parse, the mobile backend api tool about how moving from ruby to let them reduce their API server pool down by 90%, which is definitely worth reading here.
- Concurrency is baked nicely into the language. Go has has the very simple ‘go’ keyword, which is to say “go do this function in the background”, channels, which allow for buffered references of data for processing as well as parallelism by running go-routines on multiple cores asynchronously. These tools are not libraries or packages but instead primitives in the flow of the language/compiler. This means developers can write programs that with relatively little easy take full use of the CPU available and build non blocking, beautiful programs.
- It’s open source and encourages all code and libraries built to solve problems to be part of the open source community. This would provide an opportunity to make some excellent tools and libraries that could be shared with the larger software development community.
- Golang is currently the goto programming language for dev ops development. It’s what Docker was built in. If we wish to not just support dev ops for clients but continue building tools that are flexible and usable for the larger dev ops community, Golang is an excellent language for doing so.
- Mobile is still in its experimental phase, but you can currently build OpenGL applications with Golang that run on both iOS and Android as well as include callable binaries for running shared code/business logic on both platforms. There is currently no UI binding to UIKit or the Android interface builder, but I think it’ll be coming, at least for android. It wouldn’t surprise me if the next 18 months Google push it as the next language for building native android mobile apps, in the same way apple have transitioned to Swift as it’s future language moving forward.
What has my experience been like?
GoPath + Setup
My initial experiences were a little but mixed; there is some intentionally different ideas as soon as you start looking at the first tutorials and setup of Go. The first being the setup of a $GOPATH system variable and to gentle force users to store all code under a github user folder. For example, $GOPATH/src/github.com/usernamehere/helloworld. Most developers are very comfortable with their certain /code /dev or /projects folder so telling you “No, lets have a bit of structure with this” and btw, we recommend github, a very specific hosting domain, was I thought a pretty strong stance. However, I quickly started to see the benefits.
Firstly, by storing all my learning/sampling code on github.com, I was for the first time able to immediately share my problems, learnings and experiments with friends. No “I’m working on a thing, it’s cool”, but instead “Here take a look, lets collaborate”. It’s almost like slipping a little sneaky shove in the direction of “hey guys, you should look at this open source thing”; but I really enjoyed it. I forked a few examples and started building on them. I started building a little game and sharing feature development on different branches with a friend. Also, users can grab by code, documentation and all from the same path.
Simply typing go get github.com/bomer/hellochipmunk , will download and build a project. It can no be included as an import in any other project Pretty neat.
Code can be run directly for dev/testing by using go run filename.go.
go run file.go
Code be be built using go build. This will run it compile an executable ready to run/share based on their being a main.go file; else a filename can be specified.. Binaries will contain everything needed to run your program on your architecture. Compilation is very fast for a typed language due to the design of the golang compiler.
Writing code is for me is definitely the thing I like most about Golang. It’s designed to get out of the way and just let you start writing your logic. I’ll start off with a hello world and expand to show a few features I find neat in Golang. I will be running all these files using the go run command.
Pretty straight forward, func main is the main entry point to any program as it is in C based language. FMT is the formatting tool and allows standard in/output, string formating. Here we are using the Printf function to print a formatted string.
Now as I mentioned earlier, Go has no classes. What it does have is structs and structs can have functions. This gives the basics of what people often think of when they think of classes. Objects with properties and functions. However, there is no idea of inheritance, operator overloading, abstract classes or some of the traditional C++/Java style uses of Classes. Often I find very smart people use abstract classes and inheritance to design a brilliantly unreadable mess that they can produce amazing things with, and require constant jumping through files, reading documentation and code to figure out how the pieces fit together. Golang intentionally removes all of this. Golang has things that store and do stuff.
Below is a simple example defining a struct of rectangle with length/width and a name.
Second, I’m defining a function for all rectangle structs called display, that will print out the properties of the object.
Finally in the main function I’m initializing some rectangles with some different syntax and calling our function. In the first rectangle I’m using the var keyword and no named variables in the declaration. Go will just assign these values based on the order. In the second rectangle object, I’m using := to declare and assign. You cannot use this on the same variable name twice because it can only be created once. I am then naming the variables to initialize them, like JSON. I generally prefer the second option as it’s clear and neat.
3)And now…. Make it a web app!
So nothing too fancy shown off so far, pretty basic static typed language stuff. But using the Go standard library, you can very quickly turn a command line driven app into a full web api! Let me show you an update version of the previous project. You can see the lines that have changed in the side bar next to the line numbers (git gutter package for Sublime). We will add a web server, request handling and json encoding; all the usual stuff web devs do every day. The inbuilt http server is very performant and functions very similiar to the NodeJS Express server out of the box.
First off, we added two new imports, and have grouped them using brackets. GoLint (which the GoSublime plugin uses) will automatically sort these alphabetically and indent them for you.
Secondly, in the struct I added a uppercase first characters on the variable names. This is to signal to the compiler if this variable is publicly accessible or not. Without this, the json encoder will not be able to access the variables. This is easy to forget, I certainly have once or twice, but it will allow you to easily have private/hidden variables without additional keywords or even worse, comment notations! Yuck!
In the display function I also just updated the variable case of the first letter.
The new function rectangleHandler implements the interface required for handling requests/response. I will address interfaces a little more in Golang shortly.
The two parameters passed in are handled by the handlefunc (line 26) call; w/http.ResponseWriter is where the response is returned. r/http.Request. We won’t be using the request in this example, but you can easily grab post data, request type, etc. from here. We will just directly pass the ResponseWriter to the json encoder. The Json Encoder.Encode() function will just take and struct and encode it. You can also Marshal/Unmarshall (encode/decode), but this encode function is a nice one liner helper function.
Finally in the main function, we bind the default route (“localhost:8008/”) to our rectangle function. We can add additional handle functions to handle more routers.
Goroutines are lightweight asynchronus threads managed by the go runtime. The best part is how easy it is to make a regular blocking/sync call async. Put the keyword “go” in front the call! It can also be done with a closure function.
In this example, I turned rec into a global variable but putting it outside the main function.
I added math/rand and the time package to be able to sleep and refresh the values using the rand int function.
The updatedRectangle() function is a recursive function that just randomly sets the value to a number between 1 and 10, waits for 2 seconds and re-runs itself.
Finally, before I setup the http handler, I create a go routine that runs the updateRectangle recursive function. Finally I removed the local variable so the global rec variable is used instead. Now every two seconds I will get a different value returned on my api!
Interfaces is not a new concept by any means, but there a few ways which mean it critical how you code in Golang. Due to no inheritance or generics, interfaces allow for explicit ways to share code and functionality between packages, structure implementations and allow for an amazing upgradability of application components and the standard library.
In this example, I have created two structs, a Circle and a Square. Both have different properties but the same Area() function which returns a printable string based on the correct formula for the shape. The Square is in its open file in the shapes package, which we then import into the main program. This is just to show how packages/applications can be broken down to be more managable and still share a common interface.
There is also an interface that specifies anything that is considered a “Shape”, must have an Area function that returns a string.
The printArea function expects to receive an object that confirms to the Shape interface. It doesn’t matter what object it is, aslong as it has the Area() function, as specified in the Interface.
In the main function, we initilise two objects, and call our print area function. In the print function we output the value of the Area function. Without the interface we couldn’t pass any object to this function to get the value.
Finally, go automatically provide documentation lookup without any comment blocks! Take a look at the objects automatically documented here from this example. godoc.org/github.com/bomer/go-interfaces
So I think I’ve made my self stance pretty clear, I think Golang is awesome. A team starting a new project with a good API/Backend component would definitely benefit hugely from using Golang, and I think its only going to go from strength to strength in terms of dev adoption and its coming updates. I’m going to keep working with it and I hope some people here give it a crack based on this blog. I’m attaching below a few recommended places to start/read about.
- Getting Started, official golang page — https://golang.org/doc/
- Parse’s move from Ruby to Golang — http://blog.parse.com/learn/how-we-moved-our-api-from-ruby-to-go-and-saved-our-sanity/
- Tutorial — Creating a Wiki — https://golang.org/doc/articles/wiki/ (this was the first big tutorial that got me to build something useful, take this one slow to get a grasps on its concepts)
- Golang — Concurrency is not Parallelism (Rob Pike), this video I found super informative about go’s concurency and got me excited to keep coding in Golang — https://youtu.be/cN_DpYBzKso