Trying Out Go
I tried out Go this week. Firstly by going through the Go tutorial to pick up the basics, and then by writing my own program. For sentimental reasons, my first program to try something out will usually be a simulation of the card game Patience that tells you what percentage of games it wins (1 in 13 if you’ve gotten it right). My observations are as follows:
Multiple return types to return errors! I’m in love! This may be slightly coloured by my recent project where I spent an age trying to work out which error handling idiom I wanted to use, but I absolutely, a million percent, am in love with this. Part of me thinks it’s a little too easy to ignore the error return, and another part of me is reluctant to embrace it until I’ve seen it in practice in a large codebase, but those parts are small. Combined with the interesting defer mechanism and panic/recover for show stopping issues, I think the error handling mechanisms are fascinating.
gofmt. Every program should have an inbuilt “this is how your code should be formatted” tool. It would save so many pointless arguments. (I’m in the “I don’t care whether we use spaces or tabs as long as we all do the same thing in the same codebase” camp.)
“No objects” wasn’t as jarring as I thought it would be. Maybe it was because I was just writing small programs, but I liked it. Even though I’ve had 10 years in Java, it still felt more natural somehow. The idea of implementing an interface simply by making sure there’s a receiving function is neat, although part of me worries that could make understanding code difficult. Side note: I love the idea of embedding!
I still struggle with pointers. I mean, at least there’s no pointer arithmetic, but still. For a coder used to pass-by-reference, suddenly having all these ampersands and asterixes all over the place is confusing. And then slices and maps do their own thing…. Either I need to spend some time understanding the fundamentals or just write a lot more code til I get the hang of it.
go function() + channels is pretty nice and simple for concurrency. You know what, I’d have to look up how to spawn a new thread in Java. I have no idea. And that’s having worked on a system that spawned more threads than there are grains of sand (slight exaggeration).
for-loops seem a step backwards after trying out functional(ish) Java, but I don’t mind. I’ve just been getting used to getting rid of for loops with Java streams, and now here they are again. The multiple return from the range over a slice is neat, bit less code, but I still miss the concept of IntStream.range(0,10).forEachOrdered(doThing(i)) (even if that is a horrifically long expression in its own right). Then again, I do wonder if that’s just the Java developer in me that’s bought the “functional is the future” kool-aid. I’ll be completely honest, my functional code looks a mess and for-loops might have been prettier! I appreciate that Go is not trying to be that kind of a language, and it does what it does really well, and that’s more important than syntactic sugar.
There’s a lot that I’m still curious about in a real-world evolving codebase. Having been used to Java’s way of doing things, and ways to make things as safe as possible for other developers to work with, I just don’t have a handle yet on how to do the same with Go. Then again, how “safe” is code anyway, I do wonder if that attitude comes from not trusting other developers sometimes. All in all, despite it’s differences, I felt Go was somehow very natural to learn and quite straightforward yet powerful. Very interesting to see how another language works!