On Go

I wrote this comment on yesterday, and it encapsulated many of the things that are important to me in a programming language:

It’s things like how enjoyable is writing, building, and hacking with a language, that I care more for, than themes like scalability, enterprise use, or performance that the original post describes.

go doc | grep is a fucking experience. Some time ago I was editing a Go program that needed to access the file system in a general manner. I know that package os can provide an fs.FS view for the directory name I have at hand, but I don’t remember the name of the function in package os that does this. So I switch to a terminal and issue:

% go doc os | grep FS
func DirFS(dir string) fs.FS

Then I use os.DirFS in the program.

The Go toolchain is closer to feeling like a Unix thing. Each build error from the go command produces exactly one line of output. None of the go tool commands write colors in their output. But I’m glad that cargo --color never exists, and I alias cargo this way. :)

And on the hackability factor, Go programs tend to write themselves with just the standard library alone. For example, when I wrote a small static website generator binary some years ago, the program naturally hacked itself with only standard library imports and a single external markdown package. I wonder if it would have been as fun hacking it with Rust - vetting external packages and what not.

First a note on the performance aspect: the differences in execution speeds and memory overhead between languages such as Go and Rust do not matter to me in typical use. However, the differences between, say, Go and Python, matters nearly always.

To supplement the earlier point on the go command feeling more like Unix, look at how the two commands handle successful builds. Here is cargo building a main package successfully:

% cargo build
   Compiling rustexample v0.1.0 (/Users/ns/src/examples/rustexample)
    Finished dev [unoptimized + debuginfo] target(s) in 0.81s(bin)

compared with go:

% go build

The go command follows the “no news is good news” and the “avoid unnecessary output” Unix philosophies here, cargo doesn’t.

Some may argue that I should have compared the go command against rustc, not cargo, but my overall point stands as far as default Rust tooling is concerned.