To keep my technical skills up-to-date, I decided to have a look at a ’new' programming language. My usual toolkit consists of Fortran and C for high-perfomance and scientific computing. Python for machine learning, some hobbying, and scripting. Bash for even more scripting. And Javascript for some web hacking. Altough I got tired of learning a new web framework every week and gave up on the web completely. I’ve played around a bit with CUDA, Ruby, D, C++, Lua, and I’m probably forgetting some, but I wouldn’t call myself an expert in those. I am also interested in using the language professionally, so the new language should not be too obscure. (For something exotic, see my page on the elvish shell).

What I’m looking for is something simpler than C++ and Python: easy syntax, enough high-level features and a standard library that you don’t have to implement everything yourself, but with good performance. At least better performance than Python. When looking at the popular options, Go and Rust, I decided to go for Go. Rust, whatever else you might think about it, is quite complex. Although Go’s performance probably means it wont replace fortran and C, it could replace many scripting and Python use. And it could be that the much hyped concurrency of Go, combined with the gradual performance improvements Go has been making, make it fast enough to replace even some C and Fortran codes. So, let’s go!

I’ll update this page every now and then when I learn something new.

Install

Most linux distributions package a version of go.

sudo install golang

In my case, Fedora Linux 35, that is go 1.16.15, which could be a bit old.

Using a specific Go version

Download a version at the go website, and extract it at a handy location. The default on my system is /usr/lib/golang, but for my installation I’m using $HOME/Code/go/goroot. This is the directory containing the go compiler, toolchain, and supporting files. Also create a directory for installing downloaded or built packages; the default is $HOME/go, but I prefer to keep my home directory clean and use $HOME/Code/go/gopath.

$HOME
 └── Code
   └── go
     ├── goroot
     ├── go1.18.4.linux-amd64.tar.gz
     └── gopath

To start using the newly installed version, modify your environment (you should probably add this to you .bashrc or something):

export GOROOT=$HOME/Code/go/goroot
export GOPATH=$HOME/Code/go/gopath

export PATH=$GOROOT/bin:$GOPATH/bin:$PATH

Packages

Downloading and installing packages is done using the go command. Install dependencies to your current code (ie. module) using go get Install compiled packages using go install

Virtual environment

Go does not use virtual environments like python has; setting $GOROOT and $GOPATH, and your shell’s $PATH are all that is needed.

Projects are called modules, and sort-of correspond to a repository. To start a new project, create a new github repo. For example, I’ve created a new github repository called gostart, located here https://github.com/jiskattema/gostart.

Then check it out, and initialize a module:

mkdir gostart
cd gostart
go mod init github.com/jiskattema/gostart

Details are here, and some best practices are described here.

Note that it is possible to rename a module by search-and-replacing the github.com/jiskattema/gostart string in all import statements and in the go.mod file.

Write code

Project layout

For really simple projects, a single main.go and go.mod file are sufficient. For a more extensive discussion see this community attempt at standarization

Highlighting

I’m using vim’s default Go syntax highlighting.

Linting

Vim ALE supports several linters (check with :ALEInfo), including gofmt, goimports, and golint. You can run any of those using :ALEFix <tool>.

Language server

Install with:

go install golang.org/x/tools/gopls@latest

Logging and Debugging

A basic logging module is included in the standard libraray.

Running

go run main.go

Testing

Tests are in files called *_test.go, and function to run should be called TestXxx.

To run all tests run:

go test

For a step-by-step introduction, including test coverage, see this blogpost.

The testing package from the standard library can also do benchmarking and fuzzing, details are here.

Packaging

go build main.go

builds the stand-alone binary executable.

Interactive use

Go is not designed for interactive use. Useability improvements in testing and documentation should reduce the need for a REPL loop. Compilation should be fast enough not to be an issue.

Recommended packages