My first impression of Go

I heard a great podcast on https://softwareengineeringdaily.com/ featuring Brian Kernighan (I’m putting the episode in the end of this post). The podcast was about language design which is crazy. Crazy because I was just thinking about starting a new language for fun. I decided to give up on this idea, though. It would require a lot of work and I’m not sure if I would achieve good things in a short period of time. I actually have created a language for a compiler class, although I’m not really proud of the code I wrote back then. It works quite well and I learned a lot, but it’s just not well designed. Anyway, this post is not about creating a new programming language, but using a fairly new language: Go. I have heard a lot about Go and even looked into it a while back, but I never did anything with it. They mentioned Go in the podcast and I thought to myself “Ok, let’s see what this thing can do”. Here we go on this journey….

I use Ubuntu in general, so I tried to install Go on Ubuntu. I also use a mac and I installed on that system. I will describe the things I found out so far.

1. Don’t use apt-get or homebrew to install Go

Ubuntu \ MacOS

The version in the package manager is way too old. When I tried to install 1.2 was the version on the package manager, while the version out there was 1.9. This is a 3+ year old difference. They release new versions every 6 months on average.

To download go to https://golang.org/dl/, select your source and extract it.

For example, after you download the package you could run:

sudo tar -C /usr/local -xzf go1.9-2.tar.gz
export PATH=$PATH:/usr/local/go/bin

Now you can test to see if everything went well. Create a folder called hello and in a file named hello.go paste the following code:

package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}

Then execute the following commands to build and execute the program.

go build
./hello

Compile from source code

The way I installed Go on my mac was different. I wanted to try to compile the code. First, I downloaded Go version 1.4 which has the go bootstrap toolchain. You can use that to compile your code. You can either download the source code directly from (https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz) or fetch the code from the repository and checkout the 1.4 tag.

If you downloaded the tar.gz, you should extract the code with tar -xzf go1.4-bootstrap-20171003.tar.gz $HOME\go1.4. $HOME\go1.4 is the default location for $GOROOT_BOOTSTRAP. Then run src/make.bash so you can make some tools available to compile your go code.

Now download the latest version of go and extract to your /usr/local/go (the same way we did for the ubuntu). Run src/.all.bash and you are all set.

2. Go code organization

Go uses a different structure to manage installed and used packages. It follows a certain convention.

It uses a workspace folder and some folders within it. This workspace can be set using the $GOPATH variable or by default it uses $HOME/go. In the workspace you will find three folders: bin, pkg, and src. Here is the official description:

  • src contains Go source files,
  • pkg contains package objects, and
  • bin contains executable commands.

I highly recommend reading through this documentation session and create the example described there to avoid future mistakes.

3. You can use C code in Go

That was really awesome to see. It’s very easy to import C code in Go. When you do the import you just have to write in comments the C packages you want to import and then import the built-in package C (this is called CGo). Like this:

package rand

/*
#include <stdlib.h>
*/
import "C"

func Random() int {
    return int(C.random())
}

func Seed(i int) {
    C.srandom(C.uint(i))
}

I extracted the previous code from their blog post.

4. It’s easy to learn

You might have noticed that it looks like C. Well, turns out that the authors were very involved with the C language back then. If you know C and python, you’ll have an easy time learning Go. Sometimes it can be confusing, because it uses some ideas behind each of them, but at the same time it doesn’t. I recommend going through the virtual tour they have and try the exercises. It goes by pretty fast. I bet you can go through it all in a day. I only started one project which I expect to publish soon once it has some bones in it.

5. Go has its own package manager

Because Go relies on the code to be organized in your $GOPATH folder it can use a package manager. The go command line comes with the get argument which does a fetch in the git or mercurial repository and install the package. The package installed goes to your $GOPATH\pkg and its source code goes to $GOPATH\src. Let’s install gogtk3+ with this tool and use in our project.

# Libraries required by GTK3+
sudo apt-get install libgtk-3-dev libcairo2-dev libglib2.0-dev
# Pay attention to the version here. I used version 3_10. You can check the version installed with pkg-config --modversion gtk+-3.0
go get -tags gtk_3_10 https://github.com/gotk3/gotk3
mkdir $GOPATH/src/github.com/youruser/hello && cd "$_"

Within the folder create the file hello.go and paste the sample code from the README.md of gogtk3. You can find many other examples there.

package main

import (
    "github.com/gotk3/gotk3/gtk"
    "log"
)

func main() {
    // Initialize GTK without parsing any command line arguments.
    gtk.Init(nil)

    // Create a new toplevel window, set its title, and connect it to the
    // "destroy" signal to exit the GTK main loop when it is destroyed.
    win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
    if err != nil {
        log.Fatal("Unable to create window:", err)
    }
    win.SetTitle("Simple Example")
    win.Connect("destroy", func() {
        gtk.MainQuit()
    })

    // Create a new label widget to show in the window.
    l, err := gtk.LabelNew("Hello, gotk3!")
    if err != nil {
        log.Fatal("Unable to create label:", err)
    }

    // Add the label to the window.
    win.Add(l)

    // Set the default window size.
    win.SetDefaultSize(800, 600)

    // Recursively show all widgets contained in this window.
    win.ShowAll()

    // Begin executing the GTK main loop.  This blocks until
    // gtk.MainQuit() is run. 
    gtk.Main()
}

I extracted the previous code from the README.md from the gotk3 repository. Now that you have that execute the following

# It's important to use the tags version here. 
go build -tags gtk_3_10
./hello

You should see a window popping up! 🙂

6. OOP in Go

So far Go has been nice to learn. I’m still used to write code using classes, Go doesn’t have classes. This has been the most annoying(?) part. To be able to accomplish OOP you have to start using methods with receivers. Then you can encapsulate the code in structures and interfaces. The secret here is use interfaces with receivers.

Go is strictly typed. So once you create a new type, you will be able to match functions in your receivers using the new types / interfaces. In fact, you can also add functions (methods) to built in types. They explain a little bit how to do this in the virtual tour already mentioned. If you want to read more you can also click here

7.Built-in test

Go has a built-in framework that can run a couple of tests once you write in the format it expects your test to be. It’s very similar to the unit test package in python. That’s a great tool in my opinion, because it leverages developers to create tests for their projects. First because it’s doesn’t need any research about what is the best test library around there; it’s built-in. Secondly, it follows a convention and it reduces the learning curve between projects and developers. Once they know Go, they should know how tests are built within it.

Conclusion

I’m still working on learning this. I started this week and I can’t draw any hard lines here, but the learning has been easy and smooth. No complaints so far. The documentation has been very useful which is good. A good project (language/library/framework) must have good documentation and Go’s documentation so far is good (I haven’t used this language that much, though). I’m not sure how many libraries are available natively to Go, like you can find in Python and JavaScript, but just having an easy integration with C makes me less nervous. A strong ecosystem is very important to languages and frameworks and Google knows this very well.

Sources


Leave a Reply

Your email address will not be published. Required fields are marked *