Assorted things that annoy me
It’s Sunday, and that means that in preparation for the week ahead, it’s time to sit back, relax, and brood on all the things that annoy me.
A blog by Jesse Duffield
It’s Sunday, and that means that in preparation for the week ahead, it’s time to sit back, relax, and brood on all the things that annoy me.
So you’re down in the dumps because you can’t think of any good ideas for software to build. You enjoy programming, and you’d like to build something cool to show off on your GitHub profile, but you don’t want to build yet another forgettable to-do app or grocery list tracker. What if I told you there was a whole genre of software where all the fruit still hangs low?
Mauro, SHUT THE FUCK UP!
Building software is challenging, so us humans, endowed with brains better adapted to climbing trees and eating bananas than reasoning about complex systems, develop heuristics to help us navigate:
I consider myself low on the spectrum of addict-ability: I don’t smoke, I rarely drink, I don’t gamble, I don’t have a video game addiction, and I don’t snack on sweets. But every man has his kryptonite, and a couple years ago I found myself compulsively checking the front page of Hacker News and various programming subreddits for the tech world’s latest goss.
See the interview on youtube here.
The more you read up on software engineering topics online, the more you appreciate just how little agreement there is within the profession.
Most things either perish with time or are so simple (like water) that their continued existence is completely un-noteworthy. Replicators are the things in the sweet spot: things which encode information and somehow manage to buck the trend and preserve themselves over long time periods. Replicators by definition are things which are good at burrowing themselves into the future in spite of various forces in nature acting against them.
Check out my post about this timeless open source topic over here
TLDR: When you stick an explicit interface between two things, it may reduce the friction of changing the implementation but always at the cost of adding friction whenever you change the interface
Can’t Be Fucked
Aussie slang for not wanting to, or not having the energy and motivation to do something.
“Man, i really can’t be fucked changing the channel, let’s just watch Springer.”
- Urban Dictionary
I’m not religious but The Serenity Prayer has to be most profound invocation I know. It’s so concise that it can’t even be summarised without effectively restating it.
TLDR: The official un-corruption guide doesn’t support OSX, so I got around that with docker, and the guide’s advice did not work for me: I had to export the project’s individual sample files and concatenate them back together
It’s been a while since I wrote about Lazygit but rest assured things are ticking along in the background. I spent a chunk of my holidays on a PR to refactor some architectury things but that’s a long way off being fit for merging. Today I want to give an update on the integration test migration that I kicked off tugs at collar a few months ago now. Unfortunately I’m only halfway through (120 integration tests all up, with 60 having been migrated across).
My last post on Ruby’s unless
keyword was lucky (or unlucky) enough to get some attention in its own comments and on Hacker News. Thanks to everybody who took the time to read it and comment :)
Disclaimer: prepare for hair-splitting and nitpicking
Trailing commas, also known as dangling commas, are a formatting strategy that’s grown in popularity over time. Only 2 years ago did Prettier (a javascript formatter) start enforcing trailing commas by default, and if you read the associated GitHub issue you’ll see how hard-fought the change was. In this post I’m going to explain why trailing commas fix the problem of order-depedence and how order-dependence gets in our way in a bunch of other contexts too.
Something I don’t come across enough online is posts where the author walks through a feature they built along with all the dead-ends and refactors along the way. So this post is my attempt to add to that modest corpus with my most recent coding journey.
As I sit here in my bed with something that might be the flu (hopefully not COVID again!) it strikes me that I never used to get sick this frequently. My younger self’s immune system would kick my current immune system’s ass.
Turns out that OpenAI’s GPT playground is now in open beta, so I thought I’d prod it with some questions to see if I could learn something.
I wonder if it’s getting easier or harder to be effective in modern times. That is, to be productive and focused and move towards your goals. On one hand, we have endless learning resources at our fingertips thanks to the internet. Nearly every question we can think of has a clear and articulate answer waiting for us on the other side of a google search, and where yahoo answers once held monopoly over the Q&A space online, we now have more mature alternatives like Quora and Stack Overflow.
I am not an authority on this topic: what follows is advice that works for me and for others who have taken the advice on board.
I am not an authority on this topic: what follows is advice that works for me and for others who have taken the advice on board.
Yesterday, while running a session at work on Rust, I offhandedly remarked ‘I think we can all agree that when writing unit tests, private methods shouldn’t be directly tested except in some special situations’ and to my suprise, I had thought wrong. A mini-debate erupted where various people argued mutually incompatible viewpoints. We quickly moved on from the debate but I was left a little embarrassed that I had misjudged the developer zeitgeist.
A while back I was listening to a podcast where a couple of comedians discussed the consequences of doing a Netflix special (as I type this I realise it was almost certainly Joe Rogan’s podcast). The idea is that you spend all this time building an hour of golden comedy material and for any live audience you perform in front of it’s completely novel and hilarious, but it’s also the comedian’s dream to capture that content in a Netflix special and have the whole world give you their attention (and indirectly their money) in return for that content.
My own confidence in this post: 70%
When you have a newly introduced bug and you don’t know which git commit introduced it, what’s the best way to find that commit? Typically it’s easy enough to find an example of a commit for which the bug is not present (e.g. the last release) but finding the problematic commit between then and now is the hard part. If you have a set of 100 commits, and any commit could have introduced the bug, you could go through one by one, testing to see if the bug is present or not, but that’s inefficient! You’re better off picking the commit in the middle, seeing if it has the bug, and then narrowing down your search by a factor of two! So you’ll have 100 candidate commits, then 50, then 25, etc all the way down to one. Rather than checking 100 commits individually, you only need to check log₂(100) i.e. 7 commits.
I haven’t posted in a while so I’m going to lower my standards on this one and ramble about some loosely related ideas.
If you google ‘Code Reuse In Go’ and read through the first two pages of results, you’ll see many of the same concepts come up:
First off, let’s get the standard caveats out of the way:
Here’s an idea I’d like to see in the education system: when teaching a new concept, before introducing a formula or equation that models some phenomenon, make the case for some simpler, but incorrect, alternatives first.
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.