#StandWithUkraine

Russian Aggression Must Stop


Code folding considered harmful

2022/08/07

Tags: programming tech

Oh, hey. It's an "X considered harmful" post. This cliche was bound to happen eventually, but here goes. Prepare yourselves for hot takes!

While browsing through my Mastodon feed, I stumbled upon this post about code folding:

I am not a heavy user of code folding (in fact, I don't think I've actually ever used it), but this post made me think. And the more I thought about it, the more I agreed with the sentiment in the post. I am not sure if we can draw a clear causal relationship between code folding and the amount of software defects, but code folding definitely has all of the indications of a code smell.

Code folding is an IDE/text editor feature that allows the the user to visually hide sections of code in order to focus only on the sections that are relevant to the current context. According to Wikipedia it's actually a surprisingly ancient feature, and obviously nowadays just about all editors implement it. Emacs supports it using the hs-minor-mode and Vim allows folding using the 'zf' keyboard shortcut. From my point of view people still consider it somewhat of an IDE feature, despite at least simple versions of it having existed for decades in less-than-IDE editors.

/img/editors/emacs-code-folding.png

So, let's get back to why code folding is a code smell. Like I mentioned earlier, people generally use code folding in order to focus only on relevant parts of the program, presumably to either debug existing code or to expand on it. On the surface this seems like an innocuous and helpful feature that lets the programmer do their job. However, the key aspect to consider here is why the programmer feels the need to hide certain parts of the code.

All programming activity takes place in a particular context. That context may be a language construct, such as a function or a class, or it could be a wider context such as a file or a module or perhaps even the entire program. Usually the innermost context is the most relevant to a particular coding activity, as this context defines the values our code has been given and the operations we perform on those values. When debugging a function, you typically consider the function arguments and how those get transformed into the result for that function. The size of the innermost context is dependent on the structure of the program or the nature of the task, but generally speaking it should be as small as possible to reduce the cognitive load of solving the problem at hand.

Code folding gives the programmer the ability to reduce the current context without altering the structure of the program by simply hiding various elements of the code. The programmer can ignore irrelevant things and reduce the cognitive load of reading and understanding what the code is doing. However, the programmer is doing so by ignoring the underlying issue that caused them to reach for code folding in the first place: your code is structured in a way that irrelevant detail is screaming at your face until you mute it temporarily by hiding it.

At my work we've been trying to teach trainees to write simple and readable code. One thing that we emphasize a lot is the size of functions and code blocks with a general recommendation to keep them within a few lines of code. Longer procedures are refactored into a number of helper functions, each partitioned according to responsibility and clearly named. This way the code at the top level is just a sequence of function calls and the minimal amount of control structures to represent the logic.

The neat part of this approach is that you can get a properly sized and understandable view into the program's structure at any level: you can just look at the top-level sequence to make sure everything is executed in the proper order or you can drill down into the details to find the exact behavior by following the function calls. Every editor worth using comes with either LSP integration or some kind of way to at least execute dumb jump-to-definition actions using grep.

When you fold code, you are essentially admitting that the code is not structured in a way that facilitates ease of reading and understanding. But, rather than address the issue, you side-step it at least for now in order to focus on your current task. This is potentially a valid choice and we have a word for this exact thing: technical debt. However, the issue ultimately remains and it's entirely possible that your code folding isn't actually entirely accurate and may end up missing critical detail hiding among the irrelevant noise, which will slow you down. If you were not using code folding you'd probably get annoyed at the poor readability and be more encouraged to fix the problem.

Like every other "X considered harmful" post ever, here comes the inevitable back-pedal: I am obviously not going to say that you should never code fold ever. We all have to deal with low-quality code every now and then and sometimes it's just not possible to undertake a refactoring in order to finish a task on time. In that situation it makes sense to utilize every tool at your disposal to just get through that task as easily, quickly and correctly as possible. But, when you do fold sections of your code I would like you to think even for a split-second why you are doing it and if it would be worth your time to restructure some of your code instead. Maybe that loop you hid should be extracted into its own helper function? Maybe that class has too many responsibilities and those methods you hid should belong elsewhere? Perhaps you can leave the code in a state where the next reader won't even need to think about using code folding.

>> Home