Golang is GO GO GO!

@ipyandy Tweet

You will have to be a programmer if you’re going to be a network engineer in the future, they say. I don’t agree, but it surely helps you do your job. But what language should you learn? Perl? (no) Python? (maybe) Ruby? (perhaps) Every time I say something about learning Python, a little voice on Twitter says Or Go!. Go? Go. And so, sucker that I am, I gave it a go (pun intended). TLDR: I think you should, too.

The Go Programming Language

The name Go feels like it should be a terrible word to search for on the Internet because it’s so short, but searches actually work remarkably well if you use Google Search. Compare the results of a search for “go if then else” from Bing and Google below; I’ll let you guess which is which:

Go Search Comparison

Maybe Google has learned from my search history. So, what’s important to know? Go is:

  • Open source. The source code is readily available and can sometimes be helpful to figure out what’s going on.
  • Free, obviously
  • Pretty fast
  • Multi-platform (Linux, OS X, Windows for starters)
  • A compiled language
  • Strongly typed
  • Capable of concurrency and multithreading

As a Perl programmer used to the extremely lazy (and sometimes dangerous) automatic casting of variable between data types as needed, writing in a strongly typed language takes a little more work than I like. However, the benefits of doing so are well established, and in the end so long as things work, I’ll live with it.

The Go Playground

Go to http://golang.org/ and on the front page there’s a little Hello World script that you can click a button to run it. Go on, try it. Now edit the code and run it again. That’s pretty handy, and in fact the Tour (an introduction to the Go language) includes editable, runnable examples on every page. Want to share code with a friend? Add it to http://play.golang.org/ then click the Share button; the website takes a snapshot of the code and generates a unique URL you can send out (with obvious security implications, but to try out an algorithm with help, it’s fantastic). It’s a small feature, and really it’s a browser feature rather than a Go feature as such, but it’s a really nice way to introduce people to the language.

Why Go? Why Now?

Here’s what got me thinking that I should try Go finally. I have been playing around writing a REST API client so I can do some automation, and my previous efforts have been in Perl and Python. While I’m very comfortable with Perl, and I love the way JSON data can be handled, the web connection side of things was beginning to feel kind of clunky and I’m never truly happy with my code. I started by looking at the Hello World code (because who doesn’t?):

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}

Even I can understand that, so I started searching for more examples and came across something like this to grab a web page:

package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
    "os"
    )

func main() {
    response, err := http.Get("http://golang.org/")
    if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    } else {
        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Printf("%s", err)
            os.Exit(1)
        }
        fmt.Printf("%s\n", string(contents))
    }
}

This feels oddly like familiar territory. It’s not a lot of code to get a web page downloaded and print the output, and that includes some basic error handling. I looked at this and thought If it’s as simple as that to get a web page, writing my REST API client is going to be simple!

Of course, I know better now, but still, there’s a certain elegance to the language. Plus — and this is a huge win over Python for me personally — it uses curly braces rather than indentation to define code blocks, which makes me feel all warm and fuzzy. What’s not to like?

Cross-Compilation

I wrote a (very) basic REST client as planned, then I wrote a couple more. The first – with some generous Twitter help from Kale Blankenship (@vCabbage) extracted the data of interest from a JSON response. JSON turned out to be an interesting change from Perl, and I’ll maybe talk about that in another post, but with Kale’s help it suddenly made sense and I was able to progress past my own stupidity. The next couple of clients were built on the same code base, take a bunch of command line arguments to reformat and turn into an API call, then, in the first implementation – receive a plain text response which can be printed back to the user. It’s the first step in migrating some of my tools from being fat clients run directly by the user, to being thin clients calling a REST API, and the results being calculated in the background by the server, which is also where the data resides. This way I can make the tool’s functionality available to users on their local machine without them needing access to the data. My users, however, are a mix of linux, OS X and Windows users, and this is where Go just came into its own.

Go 1.5 has made cross-compilation so easy it’s ridiculous. Here’s how I build a client for OS X:

env GOOS=darwin GOARCH=amd64 go build my_rest_client

This command sets the environment variables GOOS (Go OS) to the target operating system, and GOARCH (Go Architecture) to the target CPU architecture. The rest of the command (go build my_rest_client) tells go to build the client. In actuality, since I’m running Go on OS X 64-bit, I don’t really need to define the OS and Architecture as they’re already known. Still how about 64-bit linux on Intel?

env GOOS=linux GOARCH=amd64 go build my_rest_client

Yup. Want to guess how compiling a client for Windows looks?

env GOOS=windows GOARCH=amd64 go build my_rest_client

I gather that before Go v1.5 it wasn’t that easy, so I’m grateful that I came to the language now! The list of valid GOOS and GOARCH values includes freebsd/netbsd/openbsd, plan9, solaris and architectures include 386, amd64, arm / arm64, and ppc64, so yes, Raspberry Pi ARM linux builds are possible.

With a simple shell script, one command builds executables for all my target clients. Compared to helping people install Python or Perl and getting all the necessary modules installed, this is positively a dream.

My 2 Bits

Go is not, shall we say, as easy a move as I’d like it to be. As a lazy perl programmer, moving to a strongly-typed language makes things interesting. However, I’ve managed to achieve quite a few things all using core libraries, where Perl would have had me installing multiple modules and many tens of dependencies along the way. I’m going to try and stick this one out, because it seems like Go has the potential to do some cool stuff with relatively little effort.

In a future post, I’ll run through my basic REST API client code, and hopefully the relative simplicity will inspire one more person to give Go a chance. We’ll see if I still like Go in a year, but for now — with very shallow exposure to the language — it gets two thumbs up.

4 Comments on Golang is GO GO GO!

  1. Kale came back on Twitter with an optimized version of the above (See? TMTOWTDI!) which I like:

    package main
    
    import (
    	"io"
    	"log"
    	"net/http"
    	"os"
    )
    
    func main() {
    	log.SetFlags(log.Lshortfile)
    	
    	response, err := http.Get("http://golang.org/")
    	
    	if err != nil {
    		log.Fatalln(err)
    	}
    	defer response.Body.Close()
    
    	io.Copy(os.Stdout, response.Body)
    }
    

    With his additional helpful comments, you can see it in the playground: https://play.golang.org/p/4SpfD4bGe5

  2. I prefer to use javascript (JS) and nodejs. JS also uses curly braces rather than indentation to define code blocks. Plus overwhelming number of libraries and package manager. JS works in browser, server-side (nodejs), mobile and noSQL database like mongodb. Recent version (ES6) has all the missing parts.

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.