First off, let’s get the standard caveats out of the way:
Standard preface: the purpose of this series is to put absolutely everything that bothers me about Go on the table to see who can relate. I’m not in the take-down business, I’m in the nitpicking business. So if you leave a comment saying ‘This is just nitpicking’ I will have no choice but to completely agree with you. I am not suggesting you will run into these issues on a daily basis, I am suggesting that when you do inevitably run into them, it will be frustrating. I don’t expect Go to change and I appreciate why people don’t want it to change.
Before we start, let me make something clear on the back of the comments from the first post: this series is my attempt to put absolutely everything on the table that frustrates me when using Go. As such, I’ll be doing some extreme nitpicking, much of which people will consider overblown or shortsighted. But my goal is not to do a take-down of the language (I’m stuck writing in it for now anyway), I really just want to get a feel for how many Go devs there are who share my grievances. If none of my grievances bother you, that’s fine: we probably differ on values (or I’ve missed something obvious).
My post on Go’s error handling spurred some debate around rust’s ‘?’ operator and whether it would be a good idea to try and import it into Go. There are three main arguments against doing this:
Recently I wrote a post on type keys which a reader of the blog posted to Reddit where it was generally well-received, but garnered enough feedback for me to promote type keys from ‘anti-pattern’ to ‘code-smell’, and include a counter-example where type keys were the lesser of all evils. The post to Hacker News gained no traction but I was satisfied enough with the feedback from Reddit.
I’ve been using Go for a few years now, mostly in my open source project Lazygit. In my day job I use Ruby and Typescript, and I’ve also spent some time with Rust. Each of those languages have design quirks that can grind a developer’s gears, and although my own precious gears have been ground by every language I’ve used, Go is the only language that has made me feel indignant.
A couple times somebody has told me about the latest COVID super-spreader and then asked the question ‘how come it’s always somebody who visits 5 different places in a single day. Who the hell are these people?’. Recent examples aren’t hard to find: so-called super-spreaders do get around. But when you think about it, this question has an obvious answer: highly mobile people are more likely to contract COVID in the first place. If they happen to also be mobile on the day they infect a bunch of other people, their super-spreading isn’t super-surprising.
Do you remember when you wrote your first program? I do: back in primary school my dad gave me a copy of ‘The Games Factory’: a GUI for building 2D games with raster graphics. I didn’t write a single line of code: it was just a matter of checking a bunch of options and arranging objects on a screens. But from day one I was hooked, and now years later I’ve made programming my career.
Note: On the back of some feedback I’ve created a follow-up of this post where I refine the thesis. I’ve left this post as-is for the sake of comparison
This post belongs in the ‘highly speculative’ category. It contains ideas that I’ve yet to flesh out and properly pin down. Reader beware!
Say we wanted to create an Accordion component that lets us expand and collapse sections within the Accordion, such that only one section can be expanded at a time. This is a good candidate for a Compound Component. Let’s first create an Accordion with three sections, without trying to abstract out any logic.
Spoilers below. For those who haven’t read or watched the series by now, it’s your own fault.
Recently I’ve been working on a feature in my open-source pride and joy, Lazygit, that allows viewing your modified files as a tree rather than a flat list. This allows you to get a better feel for which areas of the codebase have been changed, and has some perks like easy navigation with folder collapsing, and the ability to stage/unstage whole directories.
What you are about to hear is a tale full of danger, excitement, and personal growth. You will come across the evil Dragon Of New Requirements, and the Serpent Of Typescript’s Lacking Type Inference. Polymorphism spells will be cast, Abstractions will rise and fall, and chests of various colours will explode. Although this tale requires no advanced knowledge, it will require courage and persistence, because it is a terrifying tale of twists and turns that, in real life, spanned weeks.
Over the last couple of days I’ve been working on LazyMigrate, a gem which provides a little UI for handling migrations in rails. Because it’s a gem that depends on your Rails app’s code, it can’t really be tested in isolation (unless I went and mocked out a heap of stuff which would erode my confidence that things were working correctly). I was vaguely aware that I could have made a Rails plugin, which sets you up with a mock rails app for testing, but I wanted to be able to run the gem from outside rails as well.
The second half of this blog post now lives in video form here
In The Pragmatic Programmer, Andrew Hunt and David Thomas introduced the DRY (Don’t Repeat Yourself) principle. The rationale being that if you see the same code copy+pasted 10 times you should probably factor that code into its own method/class.
As a software developer I like to think of myself as intelligent and discerning, but if I’m being completely honest with myself most of the decisions I make around code structure are governed by fairly low-resolution heuristics like ‘Don’t Repeat Yourself’ and ‘Keep It Simple, Stupid’. My stylistic intuitions all too often get priority over intuitions about long term maintenance and extensibility, in part because there are always arguments available that sound very serious and programmery but really just cover for the stylistic bias.