I've been doing poorly on my engineering notes recently, mostly because I haven't been having many successes worth writing about. On the other hand, I did manage to get something working in Go.

At work, we had a problem: We wanted to deploy CookieCutter, but we wanted it deployed as a service and we wanted it deployed in a Golang only environment. So I ended up re-writing the core algorithm in Go and hooking into the server and it more or less works.

I... really don't like Go. At all. It's weird ad-hoc polymorphism with three-feature signatures just feels all wrong and broken to me. People used to call Python a "bondage-and-discipline language" because you were not allowed to be sloppy, at all, with your whitespace. Go makes Python look positively libertine. You are not allowed to experiment in Go. Warnings are errors— if you block out some code, you have to block out any imports that are referenced only in that code. It makes for an annoying development experience. Go is not only for mediocre developers1, but it genuinely makes potentially great developers into mediocre ones by constantly discouraging developers from trying any harder.

I mean, I get it. For what it does, Go does it really, really well. And it probably is the best thing in the space it occupies right now. But that space just feels dumb to me.

But here's what I have learned:

The cheesiest way to test if a file is a binary is to open it, read in 512 bytes, and ask the UTF8 library "Does this look like valid text to you?"

The Filepath library looks exactly like Python's. Walk() even works more or less the same way.

I really wish Go had generics. That programmers could use. It obviously does have them— lists and maps can take interface{} as an arbitrary value type!

The OS library looks exactly like Python's.

So does the Path library.

I really wish Go had higher-kinded types, if only so error-handling monads and railway-oriented programming could be a thing.

Although it's not well-documented, in recent versions of Go the object returned by bytes.Buffer() implements io.Writer, so we can all stop implementing our own Read() and Write() methods on top of str.

The Templating Library is awkward, using the Clojure-ism (!) of a leading dot to distinguish between a symbol lookup and a symbol invocation. But it's nicely powerful and feels a bit like Jinja2.

The Go version of shutil.copy() does not reproduce the file permissions of the source correctly. Write your own.

For such a damnably restricted language, the documentation tool is unforgivably louche.

I really wish Go had macros.

Go has closures. It has functions as first-class objects. It's lack of the features that came with these is inexcusable.

The ioutil.TempDir() works exactly like the Python version.

I really wish Go had an implemented version of du(1). Guess I'll have to write that myself.

The syscall.Statfs() works exactly like Python's os.statvfs.


Rob Pike, the principle architect of Go, wrote of it:

Our programmers are not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.