Three Levels of Indentation

Posted on May 7, 2021

The Linux Kernel Coding Style includes this famous rule, apparently written by Linus himself:

Now, some people will claim that having 8-character indentations makes the code move too far to the right, and makes it hard to read on a 80-character terminal screen. The answer to that is that if you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program.

This is known as the Three Levels Of Indentation Rule, although “rule” is a word that usually doesn’t fit well to anything related to programming, IMHO.

I do not really abide to the Linux kernel coding style, but to a personal extension to the suckless coding style guidelines (as they themselves put it).1 However, I do follow the Three Levels Of Indentation Rule as part of those personal extensions…

…except where I don’t! Behold this snippet from 20b5922@scalc (comments added for clarification):

static int
eval(double *dest, const char *expr, Stack *stack)
	/* ... */

		for (arg_i = op_ptr->argn - 1; arg_i >= 0; --arg_i) {
			err = stack_pop(&args[arg_i], stack);
			if (err != STK_SUCCESS)
				return err; /* 4 levels of indent!! */

	/* ... */

Horrible, isn’t it? Well, it is at least to me, and it isn’t really about aesthetics. It isn’t about Torvalds being some kind of religious leader we all ought to blindly follow. It’s about complexity; it always is!

Every level of indentation signals a new level of complexity introduced in your code,2 be it a loop, a condition, a new procedure, even a data structure definition. If you’re indenting, you’re adding complexity to the mix.3

Three is an arbitrary number, of course. It does hit a sweet spot, though, which I guess comes from lots of collective wisdom in the dev community? Maybe it’s just the C community? But I have noticed that the Three Levels Of Indentation rule is quite useful also in contexts like shell scripting.

But again, rules in programming are not rules… If a so-called rule becomes an obstacle for your vision… throw it out the window! If it makes writing your code harder, why bother. You know that “rule” some people have against using goto statements? I followed it for years until I noticed that goto works really good to break some kinds of loops I tend to write… and make my code easier to read and mantain! It’s very probable that your way of writing those loops makes it unnecessary for you, though.

Programming is a science and an art! There is personal expression in code, even if the problems we solve are objective engineering problems. A CPU doesn’t care about your feelings, but your feelings and mood affect how you write your code… Programming languages are human languages. Programs are human creations.4 In art, you first learn the rules and then you learn to break them!

Will I fix those 4 nasty indentation levels in that snippet? I probably will, but because my gut tells me there’s room for improvement… Expect very, very awesome code coming to the repo (or interesting breakages!)

  1. I plan to document it in the future! ↩︎

  2. Assuming you’re consistently indentation according to the same criteria across the entirety of your code, that is. What kind of evil mastermind would do otherwise?? ↩︎

  3. This doesn’t imply that lack of indentation signals less complexity. Think your typical BASIC spaghetti code full of unstructured jumps! ↩︎

  4. I had this project many years ago about studying programming languages as human languages, from a Linguistics POV. I’m not really sure why I left that unfinished, even after presenting a paper in a Linguistics conference… I got so much backlash… that might’ve been the reason, I guess? ↩︎