Human Who Codes Newsletter - Code Spelunking


Thoughts on Code Spelunking

My recent work on ESLint led me into a part of the code I didn’t write and am very unfamiliar with: code path analysis. Code path analysis is another type of static analysis that ESLint does that traces code execution throughout a program, constructing code paths and branches with every condition that it comes across. As a simple example, an “if” statement may cause a branch if the condition evaluates to true. Code path analysis is what lets ESLint determine if code is unreachable or if a particular part of the code is related to another part.

Code path analysis was completely designed and implemented by a contributor many years back; that person has long since left the team. And because this part of the code was written long before we had an RFC process in place, we don’t have any design documents describing how it actually works. Aside from sparse comments throughout the code, I’ve considered it “magic” and tried to avoid it as much as possible.

However, avoiding it no longer is an option as we’re planning a rewrite of the core. So I decided to start exploring the code to finally figure out how it works. I call this process code spelunking.

Spelunking is the practice of exploring underground caves, frequently without the use of maps. It’s a hobby people undertake because they enjoy exploring the unknown, potentially getting lost, and finding their way back. To make matters worse, underground caves are, by definition, completely dark, which means that you can only see just a small amount of what surrounds you. I find this to be an apt comparison to learning code you didn’t write.

So how can you familiarize yourself with unfamiliar code?

Start small. The first thing I did was try to find the smallest atomic piece of code that I could understand. That code was a single function called “remove” that I discovered was simply searching an array for a given value and then removing it from the array. So I renamed the function “removeFromArray” and went from there. Next, I found a small class that represented a segment of a code path. I went through and made sure I understood what each property represented and what each method did. From there, I moved on to other classes.

Break things. Once I thought I understood how some of the methods worked, I intentionally broke them. I commented out one line here or changed one line there and re-ran the tests to see how that change broke the code. In some cases I was correct in how I thought the code worked; in many cases I was completely wrong. But because I had the tests to rely on, I was able to see how small changes affected the larger code base while ensuring that I could get back to a last-known good state.

Leave breadcrumbs. After getting more familiar with the code base, I started leaving comments everywhere I could. I updated JSDoc comments to help VS Code understand what types we were dealing with, I left big block comments in the middle of complicated parts of the code explaining what I had learned by breaking things, and I took note of any parts where I still had no idea what was going on. I refactored object literals into classes to better represent the data. This culminated in a couple of pull requests that added these comments back into the code, ensuring this new knowledge would not be lost going forward.

Write documentation. The last step, which I haven’t reached yet, is to write (or in this case, rewrite) documentation. With a complicated part of a system, expecting people to read through all of the code to really understand it just isn’t practical. Where there isn’t already a design document, it makes sense to go back and create one retroactively to make sure that newly-won insights aren’t lost along the way.

Code spelunking can be a time-consuming, frustrating process, but ultimately it’s worth it to ensure that you understand how important parts of the system work. So far, I’ve spent about two weeks going through this code and I’m only about half way through. Even though I’d much rather be writing code, I know that the time I spend code spelunking now will pay off down the line.

Key Takeaways

  • You can't avoid code you don't understand forever. At some point, you'll need to go code spelunking.
  • Find the smallest part of the code that you can understand and go from there. Try changing the code in small ways to see what breaks.
  • As you're code spelunking, make sure to leave comments and write documentation so your newfound knowledge isn't lost along the way.

💻 Free e-book: Managing Your Interrupt Rate as a Tech Lead. Last month, I wrote three blog posts about managing your interrupt rate. Due to popular demand, I've compiled those three posts into a short e-book with a new frequently asked questions section for each post. If you're a tech lead who's having trouble dealing with constant interruptions, you can download it for free.


Stuff I've Enjoyed This Month

🎬 The Future of Movies, expained with MKDHD by Cleo Abram
A quick tour through the latest and greatest in motion picture computer-generated effects. If you're still thinking in terms of green screens, this is an eye-opening look at how movies (and some TV shows) are using computers today.

🎬 Try this the next time you have an uncomfortable conversation by Simon Sinek
If you're involved in leadership, and sometimes even if you're not, you're destined to have uncomfortable conversations with other people. This short video gives you a framework for having those conversations in a way that minimizes both personal discomfort and the possibility of it ending badly.

📝 CSS Nesting by Adam Argyle
CSS nesting gives you the ability to nest rules inside of each other. Just shipped in Firefox 117, CSS nesting is now supported in all major browsers, so it's worth reading up about it again.

📝 A guide to designing accessible, WCAG-conformant focus indicators by Sara Soueidan
Focus outlines are an important part of overall website accessibility, yet people often mistakenly remove them or otherwise render them useless through careless CSS. This article explains why focus indicators are important and how to stay compliant with current Web Content Accessibility Guidelines (WCAG) when modifying focus indicators.

📚 The Confidence Game by Maria Konnikova
I really enjoyed this book that delves into how con artists operate and why even the smartest people can be taken in by a skilled con artist. We are programmed as social creatures, and con artists take advantage of this in a number of ways to get us to do things that we wouldn't normally do. If you're interested in social interaction, you'll find this book fascinating.

📚 How to Work With (Almost) Anyone by Michael Bungay Stanier
This book presents a framework for working with other people through a particular type of conversation. The author starts by describing the point of the conversation and the steps, and then digs into each step in detail. It feels a little heavy-handed to me, but the takeaway is solid: work relationships need tending just like personal relationships do. Avoiding uncomfortable conversations might temporarily keep things going, but eventually you'll need to be a grownup and talk about things.


What I'm Working On

🏠 Real Estate: My latest BRRRR property has had several issues in the past month. First, the waste line backed up into the house and caused a real mess. I had to replace a cast iron section of the pipe and that required making a hole in the side of the house. My property manager did a great job cleaning up the mess. Then, the blower on the furnace died. Twice (the repair person used the wrong part initially). Overall, a very expensive month. Follow my Instagram for photos.

💻 ESLint: I've continued working on the language plugins project, which is how I ran into all of the code path analysis stuff. I opened an issue describing how we are mixing data and state in the same object, and how I'd like to fix that. This is the last blocker to having a language-agnostic core that will allow ESLint to easily lint languages other than JavaScript.

Human Who Codes Newsletter

A once-per-month newsletter discussing topics important to senior-level software engineers, with a particular focus on frontend technology and leadership.

Read more from Human Who Codes Newsletter

Thoughts on Weaponizing Open Source When you think of open source software, you might think of it as a gift from someone to the world. They’ve written something of value, and instead of trying to make money off of it, they’ve posted it online for anyone to use (and potentially make money off of) for free. While many projects start that way (Linux, ESLint, etc.), there’s another way open source comes into being: as a weapon against a company’s competition. Android. Perhaps the best example of...

Thoughts on Rates of Change One of the first things I realized about working in codebases is that different parts of the codebase change at different rates. There are some files that are touched very frequently while others can go months, or even years, without being touched. This fascinated me, partly because it reminded me of my closet (why do I even still have those jean shorts?), and partly because people seemed to put such little thought into optimizing their projects to reflect this...

Thoughts on Node.js, Deno, and Bun If you started working in the tech industry after 2005, what’s going on now may seem like a shock. Large tech companies continue to lay people off despite record profits. Smaller tech companies are also laying people off, and in some cases, having “quiet layoffs,” where they find other ways to reduce headcount, including offering employees three months of salary to voluntarily leave the job. As a result, there are more software engineers looking for jobs in...