A Responsible Programmer

Thumb up emoticon

In the last few years I have been asked to help savor several web projects gone bad. The quality of the projects, code, environment, documentation, and morale has been low. To know what I think is right in situations like this, I started asking myself the question, "What would a responsible programmer do?".

Clarity

Above anything else a responsible programmer values clarity. Not only does she value clear code, but also clear documentation, clear communication and a clear vision of where she and her project is going.

Coding

Write Consistent Code

The responsible programmer writes consistent code. Consistency helps other programmers read and understand her code. It lets them know what to expect. If she names constants with SCREAMING_SNAKE_CASE, they know that they wont change. When naming attributes in CSS and HTML, she will make all of them dash-er-ized, or none of them. This is easy stuff, but important. Consistency breeds familiarity. Familiarity is good, it removes worry and increases confidence.

When the responsible programmer contributes code to other projects, she will make sure that she, consistently, follows the style of the project. Sometimes it is not easy to tell what style a project uses, the responsible way is to ask what style is preferred and then use that style. By just asking the question, she will often trigger a review of the code which will help set a consistent style in the future.

By writing consistent code, a responsible programmer will make the program easier to understand and easier to maintain.

Don't Quick-Fix

A responsible programmer doesn't do quick fixes. When a bug needs to be fixed she fixes the root problem instead of fixing the symptom. If an event-handler suddenly starts receiving unnamed events the proper fix is not to ignore unnamed events but, to figure out why unnamed events come at all when not expected. She knows that fixing a symptom will only make the root cause much harder to find.

Write Short Functions

Short functions are easier to understand, easier to reason about and easier to test. It is the responsible thing to write. Enough said!

Separate Commands From Queries

CQS or Command Query Separation has become all the rave in the DDD world, but it was coined by Bertrand Meyer in the book, Object-Oriented Software Construction in 1988. A good book, read it!

The responsible programmer separates her commands from her queries because she knows that they are easier to test and that she can call the queries many times without anything bad happening. Separating your commands form your queries may be as easy as:

Refactor Mercilessly

Since a responsible programmer values clarity, she refactors mercilessly when her understanding of the system changes. She knows that the time invested in making the code a little more clear will prevent bugs and frustration in the future.

Prefer Explicit

A responsible programmer prefers explicit code over implicit code. Even though her understanding of advanced concepts such as meta-programming, monads and continuations is substantial, she prefers explicit code over beautiful abstractions. New programmers (including her future self) have a lot easier to understand code that is explicit than code that is not.

Don't Fear Advanced Techniques

Since advanced techniques can make the code a lot simpler in certain situations she never shies away from advanced techniques when she realizes that they are called for. At the end of the day meta-programming and "advanced" functional programming techniques are just tools that should be used when appropriate.

Check Boundaries

A responsible programmer always checks the boundaries of her system to make sure that invalid data doesn't enter into the core of the application. This way she can avoid defensive programming in the core domain where clarity is even more essential than anywhere else.

Wrap External Services

External services is one of the main reasons that development takes time, the responsible programmer makes sure to always wrap external services with a local interface. This simplifies both testing and exchanging the services.

External Libraries

A responsible programmer will never use an external library she doesn't trust. She will never add a library into her code base unless there is a significant reason for adding it. When she adds an external library she will learn it. She will learn how she configures it, how it is to be called, what are good practices for using it, what bugs there are, etc.

Balance

A code base can be compared to a balanced tree. A balanced tree is data-structure that will rebalance itself when new items are added to it. This makes the cost of modifying the tree more expensive but has the benefit that accessing items in the tree can be performed in an optimal way.

A responsible programmer treats her code base as a balanced tree. She will never add code without thinking about balance. She knows that if the project loses its balance it may have to be entirely rewritten to regain balance again.

The balance of the code may shift as the code matures, when a major shift is called for the responsible programmer will refactor mercilessly to obtain a new optimal balance.

Documentation

A responsible programmer writes and maintains documentation as the needs come up. The needs differ between projects, but most projects benefit from a system overview, a domain overview, a style guide, and code comments.

A responsible programmer makes assumptions all the time when coding, she writes the assumptions as comments in the code when she makes them. She tags them to make it possible to generate a list of assumptions.

The System Overview

The system overview is a drawing and a description of all the servers that are involved in the system. This includes databases, queues, web-servers, external services, etc. The description describes how the pieces fit together.

The Domain Overview

This is a drawing and a high level description of how the core domain of the system works. It includes the major concepts of the domain and what they mean.

The Style Guide

The style guide may be as easy as referring to Github's style guide or to write your own that alters someone else's. Anyway you do it, it is worth having it written down.

Code Comments

Comments in code should be very sparse and only added to point out idiosyncrasies. When assumptions are made, they can be written as comments with a tag to make it possible to generate a list. Example:

Testing

The responsible programmer tests! She doesn't test for the sake of testing or to increase code coverage, she tests to be sure that the code works as she expects it to.

She knows that dynamic environments such as Javascript and web browsers are fragile and that it is easy to break code without meaning to.

How to write good tests have been written about elsewhere and I wont spend any time on it here. I can recommend the last chapter in Sandi Metz' book, Practical Object-Oriented Design in Ruby if you are interested in good techniques for testing in dynamic programming languages.

Environments

The responsible programmer owns her environments. In a project there are at least three environments to care about, Production, Test, and Development. There is also the development machine itself.

The responsible programmer can set up all project environments with a single command that installs everything that is needed, including databases, seed data, libraries, search engines, tools, environment variables, SSH-keys. Everything!

This will allow a new programmer starting in the project to be setup within minutes. It will also allow her to experiment with anything without having to worry about destroying the setup and losing days debugging the environment.

Her personal development machine is also perfectly configured at all times. If she learns a new trick, she will immediately incorporate it into her toolset and into her configuration.

She is automatically prepared for catastrophes. If her hard disk crashes she can just buy a new one at the local supermarket and install her configuration files and be ready to go within hours.

To make this happen she always keeps backups of her configuration files. She keeps the non-secret ones on Github and the secret ones, such as SSH keys and passwords elsewhere.

Continuous Integration/Deployment

Another part of the environment is continuous integration. If a project doesn't use continuous integration it is a clear sign that it is not healthy.

The continuous integration server is just another environment and setting up a new is done with a single command just like the others.

The responsible programmer will set up and maintain continuous integration just like she does every other environment.

Scripting

In order to achieve the environment goals, a responsible programmer knows how to script. Scripting is not only essential for keeping your environments up to date, they are essential for automating simple tasks. Scripts are useful for generating code, testing, refactoring, renaming, installation, automating checklists, etc.

A responsible programmer ask herself, "When did I do something once? Never!" Writing a script that does what she wants frees her from having to remember the sequence of instructions required to do a task and let's her focus on more important stuff. It also serves as runnable documentation.

Tools

A responsible programmer knows her tools. She will always try to learn more about them and she will replace them if other tools are invented that work better. But she doesn't change her tools for the latest fashion.

The command line is a very powerful tool and so is scripting language and a scriptable editor.

Version Control

The responsible programmer uses version control to communicate with her future self and with other programmers. She knows that a clear commit message will help her and others understand what has happened to the system.

She prunes her commits. When she has made several changes to a code base she will make sure that she commits the different changes separately by using something like git add --patch. She also knows that if she commits something by mistake she can alter the commit message or add forgotten files with git commit --amend and that she can change the contents of her history with git rebase --interactive or with git reset

Projects

Own It

A responsible programmer owns her project, she will not allow anything bad to happen to her code. This is a difficult goal to achieve when she comes into a project that has already gone bad, but it is a worthy goal and not one that should be taken lightly. All projects must have at least one person who owns the code. When people start talking about the code as if it is someone else's, it is time to shut the project down.

If a responsible programmer decides to take ownership of a project, she makes sure that she has the authority to make the decisions that she deems necessary. No authority, no responsibility, it's as simple as that.

Estimation

Sometimes projects require estimates, most of the time they don't but, sometimes they actually do. A responsible programmer knows how to estimate. She knows that an estimate is just a guess and the bounds of any task, however trivial, always have a small probability of taking infinitely long to finish (earth quake, meteor strike, blackout). There is also a small probability that the code is already being written at the time of estimation.

Being aware that the code may take infinitely long to finish she is very careful not to make any promises and she is very clear about her estimates being guesses.

Don't Do as They Are Told

Some people may not see this as a sign of a responsible programmer but I beg to differ. When a programmer is told to do something, she will try to figure out what the real problem is. She may do this in several different ways. She may sit down and think through the "task" and come up with an alternate solution that solves the problem simpler or, even better, makes the problem go a way completely. She may ask questions to help clarify the problem for her. Why is this a problem? Why do you do it like this? Why? Why? Why?

Some people may not like this and tell her to "Just fucking do it!". Her reply to this is something along the lines of "Just fucking do it, yourself!" but she is usually a lot more polite so she may very well say "I don't understand what your problem is and, therefore, I am not the best person to solve it, please ask someone else."

She believes it is her job to understand what she is doing and why, and that life is too short to be a drone!

If she feels that she is not able to be a responsible programmer on a project, the responsible thing to do is to leave.

Summary

I have found that asking myself the question "What would a responsible programmer do?" liberating. It clarifies what I should do in situations of doubt.

At the end of the day, the responsible programmer can look through the commit log and see a beautiful list of tasks that she has completed. She can look through each commit and see that they are cohesive and well described by their commit message. She can git blame the code and see that every line of code that has her name on it reads well. She can look at her days work, and she can feel proud!

10 Comments

  1. fabian

    Amen.

    thanks for the write up

  2. Anders Janmyr

    @Fabian, you’re welcome :)

  3. vishnulalr

    Great article

  4. Anders Janmyr

    @vishnulalr, I’m glad you liked it!

  5. I’ve just stumbled over your article. Really nice job. A great summary on how to develop software.
    I personally would have added one section to the “Project” area: “Keep reserves”. From my experience it is always hard to plan a project (see your description of estimates). Therefore I plan reserves to handle unexpected events (bugs, stories taking longer than expected, problems in production, sickness, …). In case the reserves are not used, we take issues from the backlog agreed with the product owner.
    In addition to the “Quick Fix” section. Sometimes it’s hard to fix the root cause of the problem in time due to some constraints (production needs to be up and running again, …). Anyhow, after the “hotfix”, provide a proper solution afterwards.

  6. Anders Janmyr

    @Stephen, I totally agree that reserves, or slack, is something that is missing in most projects gone bad. I’m glad to hear someone is taking it into account.

    I also agree about hotfixes, they are necessary but, as you wrote, it is very important to go back and fix them properly as soon as possible.

  7. Anders Janmyr

    @Jennifer, you are welcome. I am glad you liked it. :)

  8. Anders Janmyr

    @”Chai is Coding”, thanks for translating it. :)

Trackbacks for this post

  1. Reading Notes 2013-05-05 | Matricis
  2. [译文]一个有责任心的程序员 | Chai is Coding...

Leave a Reply