Timeless Way of Coding

… we must begin by understanding that every place is given its character by
certain patterns of events that keep on happening there.

The above quote is in the opening chapter of one of my favorite books of all
time, The Timeless Way of Building by Christopher Alexander. Alexander is
famed in programming circles as the author of A Pattern Language which set
the stage for programming design patterns some 40 years before the Gang of
Four wrote the book.

The Timeless Way is the lesser known of his two-volume set. It sets up his
pattern book by defining why patterns are important. It is a more thorough
explanation of quality than Zen and the Art of Motorcycle Maintenance
without the personal account of a descent into madness and a focus on quality
through the lens of architecture and places. It is on my list of must read
books for anyone who takes themselves seriously as a programmer.

If you’ve ever had one of my code reviews, you’ve probably seen something like
this:

All functions need two \n characters between them

Or this gem:

Syntax of 'key' : 'value' in dictionaries will raise a flag on pyflakes.
Best to avoid.

Both of these are from a commit message this past week with some simple
cleanup, code gardening if you will, on code. My change didn’t affect what
the code did at all, but it did make sure that it was more idiomatic Python.
Pythonistas pride themselves on a certain style so much that there is even a
coined term for this: Pythonic.

The importance of these small changes is summed up in the opening quote from
this post. To paraphrase:

Things keep happening the way they happen.

By focusing on producing clean, readable, simple, uncomplicated code, you
create an environment where more clean, readable, simple, uncomplicated code
can flourish.

Tools I Use

You can stop here if you’re not interested in specific tools, otherwise, here
are a few things I use to help keep my code clean.

The editor I use the majority of the time is Sublime Text 3 (though I will
always have a soft spot in my heart for Vim). I start with these language-specific
settings in Python, which you can use by opening a .py file, then going to
Sublime Text 3 > Preferences > Settings - More > Syntax Specific - User and
copying this JSON blob into that file.

Beyond some basic settings that cause spaces instead of tabs to be used and
setting the tab size correctly, the most important part of those settings is
the rulers. There are two lines that are displayed at character 72 and 80
in every Python file I open.

Docblock comments in Python are supposed to be less than 72 characters. This
allows the docblock to be displayed indented in Python’s built-in help and not
wrap to the next line. I try hard to ensure all docblocks I write stop before
I hit that mark. The second line at 80 characters shows the point where my
Python code needs to stop.

I know many developers think that the 80-character limit is too limiting. “I
have a big monitor” I hear you say. The optimal character length
for a line of text is around 60 characters. Going much beyond that makes it
harder for the human brain to process what it’s seeing without scanning back
and forth. Plus, take your code and increase it so someone at a meet-up can
see your code sitting 20 feet away from the screen, then see how your 120
characters look.

There’s an even more practical consideration when thinking about line length.
Forcing this constraint on yourself causes you to think really hard about
what is the most effective use of those characters. Is that line really best
expressed with an 80 character string in the middle, or can that be hidden
behind a variable? Do all of those and conditions in your if statement
make your code more readable, or would an intent-revealing function help this
code? Constraints, even annoying ones, can really help hone your code design
skills.

Next up, I use the Python Flake8 Lint. This tool scans your code using
pyflakes and flags errors for you. Out of the box, it can be a little
annoying (especially when you’re learning pep8’s rules). It displays a pop-up
when you save your file and tells you all the places your code has errors.
This is really useful on your own projects, as it causes you to pay attention
to make sure that your code doesn’t raise these errors. But when you’re
working with other developer’s code, you might want to reduce the chattiness.
You can tweak the settings under Preferences > Package Settings > Python
Flake8 Lint > Settings - User. Here are the settings I use for it:

{
// run flake8 lint on file saving
"lint_on_save": true,
// run flake8 lint on file loading
"lint_on_load": true,
// popup a dialog of detected conditions?
"popup": false,
// show a mark in the gutter on all lines with errors/warnings:
// - "dot", "circle" or "bookmark" to show marks
// - "" (empty string) to do not show marks
"gutter_marks": "bookmark",
}

This adds a mark to the gutter on each line that has an error, suppresses the
popup, and makes sure that pyflakes is run when I open a file so I can see the
errors immediately. To see the actual error, I move my cursor to a line
that’s marked and this plugin displays the error message in the status bar.

These might seem like draconian tools that get in the way of coding quickly.
Coding fast and coding sloppy are not synonymous. Spend a little time working
within these constraints and your fellow developers will thank you.

Plus, you’ll be making sure that the code you write helps to create a better
codebase by increasing the quality of the patterns that keep happening there.