Let's Give It a Go

And with "Go" I mean "golang", the popular programming language developed at a company known for its even more popular search engine (and its unquenchable thirst for user data). I would like to share a few observations I made when using the language for the first time.

Timestamp Parsing

Usually code for parsing a timestamp looks something like this:

t = datetime.strptime("2006-01-02 15:04:05", '%Y-%m-%d %H:%M:%S')

Timestamp parsing is boring and annoying, so Go decided that there is a better way of doing things!

t, err := time.Parse("2006-01-02 15:04:05", "2006-01-02 15:04:05")

See? — Much better. Bonus points if you know which argument is the format and which one is the value without looking at the documentation first.

XML

Parsing XML in Go is relatively easy, and I have to admit rather neat. Definitely more comfortable to use than Python's ElementTree. Just make sure you don't make a typo in one of the field's tags (xml:...), because if you do it will be silently ignored. The tags are free-form strings that can contain anything.

type Something struct {
        XMLName xml.Name `xml:"something"`
        Version int      `xml:"version,attr"`
        Content string   `xml:"content"`
}

func main() {
        data := []byte(`
    <something version="1">
        <content>foo</content>
    </something>
    `)

        var something Something
        _ = xml.Unmarshal(data, &something)

        fmt.Printf("content: %s\n", something.Content)
}

getopt

… doesn't exist in the Go standard libary. Instead, there is the flag package.

import "flag"
var verbose = flag.Bool("verbose", false, "verbose output")

func main() {
    err := flag.Parse()
    ...
}

A program using it has command line flags like this:

foo -verbose
foo -verbose=true

The code is relatively nice, but unfortunately the usage of the compiled binary is non-standard. (There is only one minus before the argument name). Unix tools have settled on mostly two styles of arguments:

foo -v              # short getopt option
foo --verbose       # long getopt option (GNU extension)

I think the only other occurence of long options with single-dash prefix I have ever seen is in X11 tools. Why break with the de-facto standard way of doing things?

The Compiler

The Go compiler deserves a special mention. It's quite nice: it's fast and produces reasonably efficient binaries. I like it.

The compiler also has great warnings: e.g. it tells you about unused imports or variables. That way you immediately know that there is garbage in your code that can be collected. Unfortunately the compiler presents those warnings as errors, meaning the build stops and you don't get a runnable binary. That's quite annoying when developing or debugging a program: commenting out a block of code, and now suddenly you have to modify much more code because an import is not used anymore or some variables are now unused. It takes focus away from the task at hand (debugging) and puts emphasis on code grooming instead. Meh. Tools should support the programmer in doing their work, not nag them.

Semicolons

The Go grammar definition contains semicolons, but you don't see them much in idiomatic Go code. This is achieved by automatic semicolon insertion.

Another language popular on the web is well known for featuring it, but also for having some design issues (including automatic semicolon insertion).

Modules

I had problems understanding the module system. It doesn't make it easier that there are two systems; the old system, and the new system introduced in Go 1.11. In the old system, modules are not versioned and there is the whole GOPATH deal going on. Weird.

Conclusion

To me Go doesn't really seem to be designed as a general purpose programming language, but rather targeted towards a specific niche (although a big one at that) — web services. All of the necessary tools are there: Template rendering, parsing common data formats like XML and JSON, HTTP client and server implementations, hash algorithms, encryption, rudimentary SQL support, and all text is unicode.

Go also seems to suffer from ignorance towards well established patterns that are proven to work. Kinda sad, because large parts of the language are promising.


Posted on Feb 11, 2020 by Martin Natano