Back in October, I saw a junior engineer review a piece of code another engineer had written, and point out that a migration in the code would be a breaking change during deployment and that they needed to adjust their approach.
The thing was, the migration in question wasn’t a breaking change. I can see how they would have thought it was, given another code review they’d received recently. They were pattern matching, in a very logical way.
Pattern matching is what we do. As software engineers, sure, but also just as humans. Part of good pattern matching is knowing when the pattern doesn’t apply, but that takes time.
Thinking about pattern matching as one of the phases of learning a concept.
i.e. someone notices that a specific thing has been called out as “bad” in code reviews, so also calls it out as bad - but there are exceptions to every rule and this can lead to false positives.
— Adrienne Domingus (@a_domingus) October 17, 2019
I reviewed another piece of code recently for a newer engineer I’ve been working with a lot. They reached out to me afterward, wanting to talk about strategies for noticing the things I’d commented on in my review — it had all made sense they said, and once I pointed it out, it seemed so obvious. How come they hadn’t seen it themself?
Time, I said. Experience.
Pattern matching.
Someone responded to that original tweet back in October mentioning this talk about instinct by Katrina Owen of exercism.io. The whole thing is worth watching, but I’ll summarize one of the stories she tells in it that stuck with me:
Male and female chickens are not distinguishable from each other until they’re about 6 weeks old, but for industrial egg producers, this would be an expensive six weeks of feeding male chickens that won’t ever produce.
But there are people - trained “chicken sexers” - who can tell them apart at one day old, without even being able to tell you how they do it. New chicken sexers are trained by being paired with an expert and just trying it out and getting feedback until they’ve got it down. It’s just perception, instinct.
Our brains are so cool and smart! (I definitely encourage you to watch the rest of Katrina’s talk, it’s full of other stories and connections). But how does this apply to programming? Katrina gives the example of syntax highlighting - new engineers unfamiliar with this might have to spend a fair bit of time hunting down a syntax error that is preventing their code from compiling, that an experienced engineer could point out at a glance. I can think of a couple more examples:
Logging: My team switched to a new logging provider recently. I spend a fair bit of time in the logs, but hadn’t realize until this change that I was largely able to scan them to pick out what I needed without having to read much of anything — I sure noticed as soon as this wasn’t true anymore though! Just the presentation and layout of the logs meant that suddenly I had to read much more carefully to pick out the salient information. I adapted, of course, and I’m back to being able to skim quickly, but it took a few days.
Naming conventions: from whether to name variables with snake_case or camelCase to whether to prefixing functions that return a boolean value with is, these are the kinds of things that won’t impact functionality, and might not be apparent to newer engineers, but do impact the feel and readability of a codebase.
This is at least as important as being able to identify the pattern. There are exceptions to every rule. But being able to pick them out requires a deeper understanding. To know when to break the pattern on a naming convention, you need to understand why the pattern was established in the first place - that way you can identify whether (or not) your current use case actually fits into the pattern the way it appears to at first glance.
This was the missing piece for the engineer at the beginning of this post, who thought a migration that wasn’t breaking, would be. The good news is, they’d achieved the first step! They’d matched the pattern. This is a necessary step on the way to expertise. The next is noticing when something that looks at first glance like it matches the pattern, doesn’t quite fit.
Needing to know when to break the pattern also makes expert advice even more useful than it would be if pattern identification were the only goal. 👇
One of the recurring patterns that jumps out to me about many of the stories Katrina tells is novices being paired with experts. This was true for the chicken sexers, and true for other examples she gives, and hey, true for software engineers too!
Sure, our brains will eventually pick out patterns on their own and establish the pathways to make them automatic. They’ll do this even if no one tells us where they are. But they will do it so much faster if someone points us in the right direction and tells us when we’re wrong (and when we’re right!).
This is especially important when it comes to things like code review - if no one points out patterns we’ve missed or misapplied before our code gets merged into master, the pattern will actually be diluted, making it harder for future engineers, including our future selves, to pick them out next time. Consistency is key, and we can’t get there without the help of others who have gone before. (This is not an argument that there’s never a reason to intentionally be inconsistent, sometimes you have to make sacrifices in the name of improvement, but that is a conversation for another day!)