From Reddit to Red Hat, Go is in charge of critical systems across the web. Go is also a notable member of an emerging generation of languages.
"A good science fiction story should be able to predict not the automobile but the traffic jam." —Frederik Pohl
Golang looks beyond the obvious, and into the secondary effects of programming. Where are the traffic jams, and can they be avoided? Go shows that in many cases the answer to that question is yes.
Accordingly, learning Go is one of the best investments you can make as a programmer. It might be your first introduction to a compiled language, simplified concurrency, or static typing. These are all wonderful concepts that'll benefit nearly any project in any language.
A long past, but a short history
Before diving into Go, let's take a brief detour. Go's design is generally elegant and pragmatic, but a few of its features make sense only with some historical context.
That history starts with C. In many ways, C is the Latin of programming languages. It inspired JavaScript, Ruby, Python, C++, C#, and Java. A few of those languages are even written in C. It's easy to spot C's influence by looking at if/else and control flow statements in any of the aforementioned languages. C was originally Dennis Ritchie and was used to build Unix. From there, C found its way to the heart of Linux, where C has continued to be the language of choice.
Go was created by legends from this Unix and C era. While working at Google, Robert Griesemer, Rob Pike, and Ken Thompson found themselves frustrated by the common pitfalls of C-family languages. As Bjarne Stroustroup, creator of C++ puts it: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off."
Go emerged as the Robert, Rob, and Ken’s solution.
Go inherits a lot of good from C. Keywords and syntax share a canny likeness, and a procedural approach is front and center in both languages. On the other hand, manual memory management and long compile times are notable thorns in C. Go sidesteps these issues by providing garbage collection, memory safety, and fast compile time. The focus on fast compile time leads right to one of Go's other goals: productivity.
Java is the language of choice for large, enterprise-oriented development teams. Go takes inspiration from Java here, and also aims to be a strong bedrock for large enterprise development teams. On the other hand, verbosity and object-oriented programming (OOP) inheritance are notable warts in Java. Go avoids these flaws by favoring concise syntax and interfaces rather than clunky OOP inheritance models.
Similarities can also be found with dynamic languages. Go has strong idiomatic style, a la Python's PEP 8. Go favors convention over configuration, a la Ruby. Go has simple and straightforward concurrency baked into the core of the language, a la the Node.js event loop. Go differs on the implementation in each case, but the similarities remain.
All of this is to say, Go started as a way to address some longstanding flaws with C. It's since grown into a wonderful, general-purpose programming language.
Hello world
Now that we have the background, we're ready to learn Go. This guide assumes you have some background in programming already. If this is your first introduction, check out Python on CodeAcademy or Learn Code the Hard Way. They're a slower and more methodical guide for absolute beginners.
The rest of you? I assume you've got some background. Follow me, it's time to write some Go.
Step 1: Visit play.golang.org. Here's what you see:
Step 2: Click the Run button.
You just ran a simple Hello World program in Go. Easy! Let's talk about it, so we really understand it.
Line 1:
package main
The package main line will start most of our Go programs. This line just tells the Go compiler that we want to run the code directly. When we're ready to write our own packages, we'll replace the main keyword with the name of our package. Easy.
Line 3:
import (
"fmt"
)
When we need a package in Go, we import it. This might seem strange if we're accustomed to Python, Ruby, or Node.js. Go's standard library is broken up into a bunch of smaller packages. We can find the full list on the Golang site.
In this case, we're importing the fmt package, which is short for format. Gophers (i.e., what the Go community calls Go programmers) pronounce fmt as "fumpt." Now that we've run some Go code, we're gophers. Importing allows us to use the fmt package. We'll do that in the next block.
Line 7:
func main() {
fmt.Println("Hello, playground")
}
Finally we're running code. Every Go program has a function main() block, which is called the entrypoint. This looks familiar if we're C programmers and a bit odd if we're Python, Ruby, Node.js, or similar devs. In the dynamic languages, execution begins at the top of a document and tumbles down row by row. In Go, it starts at the entrypoint.
If we're paying close attention, we might also guess that the func keyword is a way to define a function. We'd be correct. (Go us!)
Inside the entrypoint, we're calling the fmt library that we imported earlier, then using the familiar dot syntax to call a method. In this case, the method is Println. That, as we might guess, prints our "Hello" message.
Style notes
Finally, some style notes. Use CamelCase for your variable and method names. That is FooBar or fooBar instead of foo_bar. Go is also opinionated about opening braces. See what happens if you insert a new line between func main() and the first opening brace {. Running the code with the brace on a new line should generate an error.
The spacing in Go is also standardized. Try deleting the tab indent before fmt.Println and then click the Format button. Go's formatting tool should always fix the indentation by replacing the tabs.
If you're like me, you might find the use of full-width tabs odd. It's a big departure from my usual coding style. Most of the Ruby and JavaScript code I write substitutes two spaces in lieu of tabs. Go is opinionated here, but thankfully I can keep writing my two-space tab heart out. Go won't mind a bit so long as it stays on my local machine. When I commit to GitHub or a publicly accessible repo, I'll just run go fmt first to fix the spacing.
An even better option is to install a plugin like EditorConfig. This will keep my Go code looking Go-like and my other code in whatever style I prefer. As a bonus, EditorConfig supports per-project settings, which is nice for languages that generally vary project to project, because they don't endorse a canonical style (like Python or Go).
The basics
We've written some Go so far, which is great. If we want to keep the good times going, we'll need to install Go on our local machine.
After that, it's time to dive into the basics. We still need to look at variables, control structures (e.g., if/else), types, and more. Go by Example is a fantastic resource for this. The official Tour of Go is a nice alternative.
The variables section of Go by Example is a good place to start on this new learning journey. Working from variables down to the structs section is a nice sized chunk for this next leg of our Go learning.
What's important here? The first takeaway is how nice static typing is. In Python, Ruby, and JavaScript, a lot of testing is dedicated to type checking. Is the input to this function the type we want? Test for the behavior if it's not. This kind of testing usually winds up being a whole lot of code.
Golang, by contrast, saves us by being statically typed. Take a look at the following example:
var hi string = "Hello, playground"
tells part of the story. The other part is told when defining a function:
func foo(bar string) {
fmt.Println(bar)
}
The function is explicit about which types it will accept. Try changing hi from a string to an int. On the next run we'll get a handy error message.
main.go:14: cannot use hi (type int) as type string in argument to foo
A quick upfront definition saves us a lot of bugs, testing, and headaches down the line.
Other notables? Go will complain if we import a package or declare a variable that we don't use. That's just a nice feature for keeping us honest. Try declaring a variable, and see what happens when you run the code without a corresponding Println.
Lastly, pointers. They can be a big hurdle if they're a new concept. Pointers are also one of Go's most valuable learning opportunities. The big thing to note here is that Go passes by value.
Passing by value means that, most of the time, Go creates a copy of a variable before taking action on it. I say most of the time, because we can override that behavior by using pointers. That's the, ahem, point of pointers. As a bonus, learning about all of this is a nice way to ease into a better understanding of memory management.
Beyond the basics
We haven't even gotten to the best parts of Go! I asked my co-workers at CoreOS (where we use Go prolifically) what they think is important. I received all sorts of answers that I don't have the character count to go into here. (If you're interested, channels, goroutines, composition, and type embedding were amongst the many suggestions.)
Instead, I'll be economic with my last few words. First, continue learning with Go by Example and the official Tour of Go. If you find yourself hungry for something meatier, Go in Action is a great book. Avoid Go Programming Language (GoPL), as that's an exhaustive reference. It's a great book, but is likely to literally exhaust you as a newcomer to Go.
If you want to learn to swim, you need to jump in the water. In other words, one can only learrn so much by reading—at some point you need to apply it. Go's pkg documentation is a great place to find examples to tinker with. Consider this blob from the net/http docs that shows you how to setup a simple webserver. Other great resources include exercism.io, and Project Euler.
Last, community! Go has Slack, IRC, and number of other channels where we can ask for help or share a laugh. I highly recommend joining.
In closing
Go is a wonderful language. it's grown tremendously in a short amount of time, becoming the bedrock for many notable projects.
I hope you have fun learning Go. And, be sure to let me know how it goes!
6 Comments