Home Home

80 columns limit

Arseni Mourzenko
Founder and lead developer, specializing in developer productivity and code quality
October 25, 2014

I recall discussing 80 columns limit a year ago with a friend of mine. It's fun to read this part now, to see how I changed, and to try to understand what could my friend tell me to convince me that I was wrong.

This is the quote I'm talking about:

I simply cannot get why would anyone enforce such absurd limitation. This feels wrong. This looks wrong. This looks as wrong as eight-spaces-sized tab in Windows Notepad; no, wait, this is even wronger.

I can understand why this was done in, say, seventies. This was an actual hardware limitation, so we had a choice: either we add line breaks in the code to avoid lines which are too long, or we learn it the hard way, through cryptic bugs. But this was a different era.

Today, I have my two (on request three) 23'' monitors. With 80 characters limitation, my Visual Studio will look empty even if I stack two files side by side.

More importantly, with no length limitation, I have an actual choice. Most, if not all IDEs display long lines as a set of lines with special arrows showing that the new line is not an actual new line. Line numbers make things visually easy too. This means that I can display the same file with its very long lines spanning the entire width of my monitor, or I can resize the window to fill only the half of my screen, and the text display is readjusted immediately. If I decide to make the document narrow, say 60 characters long, I can do that, and the text will still be displayed correctly. Now, with 80-characters limitation, the text will look stupid for any resolution outside the 80-90 characters range. Make the window wide? You'll have too much white-space. Make it narrow? It will look terrible.

Aside that, how would you like me to write any code in C#? Namespace, class and method, this makes an indent of three, which means twelve spaces. I'm now with sixty-eight characters left for the actual code, or actually sixty-four if I need to do anything useful, such as doing something in a using statement or in a foreach loop. An if in a transaction means that I have sixty characters for the actual code.

Then we ask ourselves, why are beginner programmers naming their variables a, b and c, and we blame their teachers or the stupid examples from books, where variables are actually named x, y or n. But shouldn't we blame the 80 characters limit? generalCrossLink is 16 characters long, and this is a rather short identifier. I've seen much longer ones, and I've written much longer ones myself. Sixty characters left for code means that if you're calling an instance method (so this. prefix is mandatory) with just two parameters, you are nearly sure you will hit the right edge of the page.

Not counting the fact that you simply can't enforce such limit on code such as HTML: deeply nested elements will quickly reach the limit, and not nesting them would create additional complexities at CSS level. Visual Studio's ASP.NET editor attempted to enforce such limit. Result: ugly formatting and exceptional cases to handle.

Today, the same 23 inch screens rarely display a small logo in their left bottom corner. More often, they show dark violet terminals, two and a half per screen. Today, if I write a line longer than 80 characters, the pre-commit hook gently rejects my commit: "this is not PEP-8 compliant"; "this violates jslint rules."

What happened? Simply Ubuntu 14.04 replaced Windows 8.1, vim replaced Visual Studio and Python and Node.js replaced C#.

But it was also an opportunity to discover something new: that the 80 columns limit actually matters.

First, the assertion I made a year ago is based on my narrow view of programming through the prism of C# and Visual Studio. C# tends to offset quickly; as I said, take an ordinary code: a namespace, a class, a method and a logical block, you've eaten 16 columns just for that.

Python or Node.js don't offset with the same speed. In Node.js, one may start by having a function within a callback of another function which is called inside a collection.forEach() within a function, but sooner or later, this code is refactored into well-separated and much less nested functions. In Python, you rarely find yourself nesting too much, because you simply keep things as simple as possible. Namespace-class-method is the default in C#. In Python, the default is a def at the root, unless you really do need classes.

Second, the 80 columns limit has its benefits. I first discovered that when writing Node.js code. Being forced to make lines shorter helped me to find identifiers which were too long and could easily be shortened without decreasing the readability. Actually, the readability only increased. By removing deep nesting, by simplifying complicated logic, I noticed that indeed, the limitation I hated so much a year ago is actually helping me improving my code.

Would I apply the same limit to my C# code? I hardly doubt it: given the pace at which C# code indents, it would be too risky. But it would still be an interesting experience to do in order to know how does it feel to have this limit in C#. I'm also pretty sure that having such limitations can only be beneficial for the beginners who need to learn that deep nesting, long identifiers and complicated logic is something which should be avoided.